6

Tengo un .each de JQuery que llama a una función con un parámetro por iteración, ¿hay alguna manera de retrasar esta llamada a la función? He intentado setTimeout como en el siguiente pero esto no funciona ya que la función se ejecuta inmediatamente.Demora en la ejecución de la función de JavaScript

$.each(myArray, function (j, dataitem) 
{ 
    setTimeout(function() { showDetails(dataitem) }, 300); 
}); 

function showDetails(dataitem) 
{ 
... 
} 

Tamaño de la matriz es más o menos 20, lo que estoy tratando de hacer es función de distribuir las llamadas durante un determinado período de tiempo en lugar de inmediato, alguna idea de cómo lograr esto? Estoy preparado para reescribir y reestructurar cómo se llaman las funciones para hacer esto, cualquier ayuda sería apreciada.

+3

La ejecución se aplazó definitivamente . Pero el ciclo no es así, es decir, todos los 20 'setTimout's son llamados más o menos a la vez. ¿Desea llamar a las funciones 'showDetail' una tras otra? Quiero decir, el primero después de 300 ms, el segundo después de 600 ms, etc. –

Respuesta

9

Se podría utilizar el índice de la matriz para calcular el intervalo de forma dinámica:

$.each(myArray, function (j, dataitem) { 
    window.setTimeout(function() { 
     showDetails(dataitem) 
    }, (j + 1) * 300); 
}); 
+0

Ahora que he vuelto a leer la pregunta, esto suena como lo que la persona que pregunta está tratando de hacer. +1 –

+1

¿El prefijo 'ventana' realmente es necesario? No creo que nadie eclipse el nombre 'setTimeout'. –

+0

@ Šime Vidas, prefiero usar siempre un alcance adecuado. Es solo una buena práctica. –

2

Los ejecuta todos después de 300 milisegundos. En su lugar, intentar algo como esto:

window.setTimeout(function() { showDetails(dataitem) }, (j + 1) * 300); 

Editar: en lugar de crear 20 temporizadores a la vez creo que es mejor hacerlo uno por uno. Función debe ser:

function showDetails(index) 
{ 
    if (index >= myArray.length) 
     return false; 
    var dataItem = myArray[index]; 
    //code here...... 
    //code here...... 
    //code here...... 
    windows.setTimeout(function() { showDetails(index + 1); }, 300); 
} 

Y primera llamada puede ser:

$(document).ready(function() { 
{ 
    showDetails(0); 
}); 

Este asumen myArray es llano matriz global, y se encargará de un elemento y sólo entonces llamar a la orden del día, con un retraso.

+0

Gracias, lo he intentado y funciona, he elegido la primera respuesta, ya que es más fácil para mí leer en el código. +1 :) – Maya

+0

@Maya, feliz de que esté trabajando para ti. :-) –

2

Eche un vistazo a jQuery.queue([ queueName ], callback(next)). Esto le permite poner en cola funciones que se llamarán y es lo que los efectos de animación de jQuery usan internamente.

Parece que desea implementar una cola, aunque no está del todo claro que tenga intenciones de hacerlo.

EDIT: volviendo a leer su pregunta, creo que otras respuestas coinciden mejor con lo que está buscando, sin embargo pensé que le mostraría un ejemplo de cómo lograr la ejecución de la función demorada con una cola personalizada.

Un example of how you could use a queue.

var myArray = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20], 
    output = $('#output'); 

// set the queue up 
$.each(myArray, function (j, dataitem) { 
    output.queue('queue', function(next) { 
     var that = this; 
     showDetails(dataitem); 
     window.setTimeout(next,300); 
    }); 
}); 

// start the queue running. 
output.dequeue('queue'); 

function showDetails(dataitem) { 
    output.append('<div>' + dataitem + '</div>'); 
} 
+0

Esto es realmente útil saber. +1 :) – Maya

0

Simplemente no utilizar $.each, sino algo así como:

var data = [1, 2, 3, 4, 5]; 

function showDetails(values, delay) { 
    console.log(values.shift()); //show the value 
    if (values.length) { 
    setTimeout(function() {showDetails(values, delay); }, delay); //schedule next elem 
    } 
} 

showDetails(data.slice(0), 300); //dont forget the slice, call-by-reference 
Cuestiones relacionadas