Bucle de JavaScript y espera la función

Tengo una matriz unidimensional simple, digamos:

fruits = ["apples","bananas","oranges","peaches","plums"];

Puedo recorrer con con $.each() función:

$.each(fruits, function(index, fruit) {  
   showFruit(fruit);
});

pero estoy llamando a otra función que necesito terminar antes de pasar al siguiente elemento.

Entonces, si tengo una función como esta:

function showFruit(fruit){
    $.getScript('some/script.js',function(){
        // Do stuff
    })
}

¿Cuál es la mejor manera de asegurarse de que se haya agregado la fruta anterior antes de continuar?

preguntado el 10 de septiembre de 12 a las 22:09

Formación: fruits = []. Lo que tienes es un objeto. Sólo un FYI. -

@ahren Eso no es un objeto, es un error de sintaxis;) -

¿Pero su código no tiene el comportamiento que espera? -

Lo siento, demasiado JSON últimamente, el código que estoy usando funciona bien, solo causa errores porque no puede terminar la llamada de función anterior. -

Déjame adivinar, #some_div no existe en el DOM cuando llamas showFruit, y se pregunta por qué no aparece ninguno de los elementos. -

2 Respuestas

Si desea que se agregue una fruta antes de cargar la siguiente, entonces no puede estructurar su código de la forma en que lo ha hecho. Eso es porque con funciones asincrónicas como $.getScript(), no hay forma de hacer que espere hasta que termine antes de que continúe la ejecución. Es posible utilizar un $.ajax() y configúrelo en sincrónico, pero eso es malo para el navegador (bloquea el navegador durante la red), por lo que no se recomienda.

En su lugar, debe reestructurar su código para que funcione de forma asíncrona, lo que significa que no puede usar un código tradicional for or .each() bucle porque no iteran de forma asíncrona.

var fruits = ["apples","bananas","oranges","peaches","plums"];

(function() {
    var index = 0;

    function loadFruit() {
        if (index < fruits.length) {
            var fruitToLoad = fruits[index];
            $.getScript('some/script.js',function(){
                // Do stuff
                ++index;
                loadFruit();
            });
        }
    }
    loadFruit();

})();

En ES7 (o al transpilar código ES7), también puede usar async y await Me gusta esto:

var fruits = ["apples","bananas","oranges","peaches","plums"];

(async function() {
    for (let fruitToLoad of fruits) {
        let s = await $.getScript('some/script.js');
        // do something with s and with fruitToLoad here
    }

})();

respondido 23 mar '18, 23:03

Mucho mejor respuesta que la mía: ayuda saber jQuery. - jasonfruta

fruits[i]; debiera ser fruits[index]; El último segundo cambio de nombre de variable, supongo. :-) Intenté editar, pero no hubo suficientes caracteres en el cambio. - se acerca el estado gris

@graystateiscoming - arreglado. Gracias. - amigo00

Se agregó un ejemplo de ES7 con async/await. - amigo00

Javascript en los navegadores es de un solo subproceso. No continuará hasta que regrese la función a la que llamó. No necesitas comprobar.

Respondido el 10 de Septiembre de 12 a las 22:09

... a menos que la función sea asíncrona. Pero este no es el caso en el ejemplo. - rabinowitz

La función a la que llamo llama a otros scripts, y parece que la carga dinámica de esos scripts no detiene el siguiente ciclo para continuar: fluidobyte

@Fluidbyte, necesita hacer un caso de prueba reducido: zzzzBov

Sí, por favor denos la versión más simple que pueda que no se trabaja. - jasonfruta

$.getScript() y su devolución de llamada de finalización asociada es asíncrona, por lo que esta respuesta no es correcta para esta pregunta en particular. - amigo00

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.