script multiple ejemplo desde con cargar javascript jquery ajax getscript

javascript - ejemplo - jquery getscript multiple



Usando getScript de forma sincrónica (8)

¿Sabe que $.getScript accepts una función de devolución de llamada que se llama de forma síncrona después de que se carga el script?

Ejemplo:

$.getScript(url,function(){ //do after loading script });

Tengo 2 soluciones más: una js pura una y una para carga js múltiple .

Estoy escribiendo un motor que requiere el uso de getScript bastante extensamente. Lo he puesto en su propia función, para facilitar su uso, pero ahora necesito asegurarme de que la función en sí sea síncrona. Desafortunadamente, parece que no puedo hacer que getScript espere hasta que la secuencia de comandos que carga se haya terminado de cargar antes de continuar. Incluso he intentado establecer la propiedad asynch ajax de jQuery en falso antes de realizar la llamada. Estoy pensando en usar el protocolo when / done de jQuery, pero parece que no puedo encajar en la lógica de colocarlo dentro de una función y hacer que la función sea sincrónica. ¡Cualquier ayuda sería muy apreciada!

function loadScript(script){ //Unrelated stuff here!!! $.when( $.getScript(script,function(){ //Unrelated stuff here!!! })).done(function(){ //Wait until done, then finish function }); }

Código de bucle (por solicitud):

for (var i in divlist){ switch($("#"+divlist[i]).css({"background-color"})){ case #FFF: loadScript(scriptlist[0],divlist[i]); break; case #000: loadScript(scriptlist[2],divlist[i]); break; case #333: loadScript(scriptlist[3],divlist[i]); break; case #777: loadScript(scriptlist[4],divlist[i]); break; } }


Como he dicho, es relativamente fácil encadenar llamadas Ajax con objetos prometedores. Ahora, no se ve por qué los scripts se deben cargar uno tras otro, pero tendrá una razón para ello.

En primer lugar, me gustaría deshacerme de la instrucción de switch si solo está llamando a la misma función con argumentos diferentes. Por ejemplo, puedes poner todas las URL de script en un mapa:

var scripts = { ''#FFF'': ''...'', ''#000'': ''...'' // etc. };

Puede encadenar promesas simplemente devolviendo otra promesa de una devolución de llamada a .then [docs] . Todo lo que necesita hacer es comenzar con una promesa o un objeto diferido:

var deferred = new $.Deferred(); var promise = deferred.promise(); for (var i in divlist) { // we need an immediately invoked function expression to capture // the current value of the iteration (function($element) { // chaining the promises, // by assigning the new promise to the variable // and returning a promise from the callback promise = promise.then(function() { return loadScript( scripts[$element.css("background-color")], $element ); }); }($(''#'' + divlist[i]))); } promise.done(function() { // optional: Do something after all scripts have been loaded }); // Resolve the deferred object and trigger the callbacks deferred.resolve();

En loadScript , simplemente devuelve la promesa devuelta desde $.getScript o la devuelta por .done :

function loadScript(script_url, $element){ // Unrelated stuff here!!! return $.getScript(script_url).done(function(){ // Unrelated stuff here // do something with $element after the script loaded. }); }

Se llamará a todos los scripts en el orden en que están disponibles en el bucle. Tenga en cuenta que si divlist es una matriz, realmente debería usar normal for loop en lugar de for...in .


Esto funcionó para mí, y puede ayudarte.

$.ajax({ async: false, url: "jui/js/jquery-ui-1.8.20.min.js", dataType: "script" });

Básicamente, simplemente pasé por alto la notación abreviada y lo agregué en async: false


Intente de esta manera, cree una matriz con objetos diferidos y use $ .cuando con "aplicar"

var scripts = [ ''src/script1.js'', ''src/script2.js'' ]; var queue = scripts.map(function(script) { return $.getScript(script); }); $.when.apply(null, queue).done(function() { // Wait until done, then finish function });


La respuesta de @Felix Kling fue un gran comienzo. Sin embargo, descubrí que había un pequeño problema con el .done() adjunto .done() al final del .getScripts() devolvía el resultado si quería "funcionalizarlo". Necesita la última promesa de las iteraciones .getScript() encadenadas desde dentro del bucle. Aquí está la versión modificada de su solución (gracias, BTW).

Enchufar:

(function ($) { var fetched = new function () { this.scripts = []; this.set = []; this.exists = function (url) { var exists = false; $.each(this.set, function (index, value) { if ((url || '''') === value) { exists = true; return false; } }); return exists; }; this.buildScriptList = function () { var that = this; that.set = []; $(''script'').each(function () { var src = $(this).attr(''src'') || false; if (src) { that.set.push(src); } }); $.merge(this.set, this.scripts); return this; }; }, getScript = $.getScript; $.getScript = function () { var url = arguments[0] || ''''; if (fetched.buildScriptList().exists(url)) { return $.Deferred().resolve(); } return getScript .apply($, arguments) .done(function () { fetched.scripts.push(url); }); }; $.extend({ getScripts: function (urls, cache) { if (typeof urls === ''undefined'') { throw new Error(''Invalid URL(s) given.''); } var deferred = $.Deferred(), promise = deferred.promise(), last = $.Deferred().resolve(); if (!$.isArray(urls)) { urls = [urls]; } $.each(urls, function (index) { promise = promise.then(function () { last = $.getScript(urls[index]); return last; }); }); if (Boolean(cache || false) && !Boolean($.ajaxSetup().cache || false)) { $.ajaxSetup({cache: true}); promise.done(function () { $.ajaxSetup({cache: false}); }); } deferred.resolve(); return last; } }); })($);

Puede ignorar la función recuperada (lo implementé para reducir posibles llamadas redundantes, razón por la cual secuestré .getScript() ) y ver dónde está la last variable establecida dentro del método .getScripts() . El valor predeterminado es un objeto diferido resuelto, de modo que si la matriz de URL está vacía, se pasa al resultado devuelto para adjuntar la .done() externa .done() a. De lo contrario, inevitablemente se asignará el último objeto de promesa de las llamadas .getScript() encadenadas y, por lo tanto, garantizará que todo permanezca sincrónico desde fuera de la función.

Devolver el objeto diferido creado inicialmente no funcionará si lo resuelves antes de devolverlo al invocador (que es lo que debes hacer según la documentación oficial de jQuery ).

Ejemplo:

function loadStuff(data) { var version = { ''accounting'': ''1.2.3'', ''vue'': ''1.2.3'', ''vueChart'': ''1.2.3'' }; $.getScripts([ ''https://cdnjs.cloudflare.com/ajax/libs/accounting.js/'' + version.accounting + ''/accounting.min.js'', ''https://cdnjs.cloudflare.com/ajax/libs/vue/'' + version.vue + ''/vue.min.js'', ''https://cdnjs.cloudflare.com/ajax/libs/vue-chartjs/'' + version.vueChart + ''/vue-chartjs.min.js'' ], true) .done(function () { // do stuff }) .fail(function () { throw new Error(''There was a problem loading dependencies.''); }); }


Simplemente cree un nodo de script, establezca su propiedad src en el JS que desea cargar y luego agréguelo al encabezado:

var myScript = document.createElement(''script''); myScript.src = "thesource.js"; document.head.appendChild(myScript);


esto es lo que hago

function loadJsFile(filename) { $.ajaxSetup({ cache: true }); var dloadJs = new $.Deferred(); $.when(dloadJs).done(function () { $.ajaxSetup({ cache: false }); }); dloadJs.resolve( $.getScript(filename, function () { }) ); }


var getScript = function(url) { var s = document.createElement(''script''); s.async = true; s.src = url; var to = document.getElementsByTagName(''script'')[0]; to.parentNode.insertBefore(s, to); };