w3schools una tipos termine que programacion pasar parametros pagina funciones funcion esperar ejecutar desde cargar asincronia asincrona antes javascript asynchronous

una - programacion asincrona javascript



¿Cómo puedo esperar al conjunto de funciones de devolución de llamada asincrónica? (6)

Tengo un código que se ve así en javascript:

forloop { //async call, returns an array to its callback }

Después de que se realicen TODAS esas llamadas asincrónicas, quiero calcular el mínimo en todas las matrices.

¿Cómo puedo esperar a todos?

Mi única idea en este momento es tener una matriz de booleanos llamada done, y establecer done [i] en true en la i-ésima función de devolución de llamada, luego decir while (no todo está hecho) {}

editar: supongo que una solución posible, pero fea, sería editar el conjunto hecho en cada devolución de llamada, luego llamar a un método si todos los demás están configurados desde cada devolución de llamada, por lo que la última devolución de llamada para completar llamará al método continuo.

Gracias por adelantado.


Esta es la forma más clara en mi opinión.

Promise.all

FetchAPI

(Por alguna razón, Array.map no funciona dentro. Entonces funciona para mí. Pero puedes usar un .forEach y [] .concat () o algo similar)

Promise.all([ fetch(''/user/4''), fetch(''/user/5''), fetch(''/user/6''), fetch(''/user/7''), fetch(''/user/8'') ]).then(responses => { return responses.map(response => {response.json()}) }).then((values) => { console.log(values); })


No has sido muy específico con tu código, así que voy a inventar un escenario. Supongamos que tiene 10 llamadas ajax y desea acumular los resultados de esas 10 llamadas ajax y luego, cuando se hayan completado, quiere hacer algo. Puedes hacerlo así acumulando los datos en una matriz y haciendo un seguimiento de cuándo ha finalizado la última:

Contador manual

var ajaxCallsRemaining = 10; var returnedData = []; for (var i = 0; i < 10; i++) { doAjax(whatever, function(response) { // success handler from the ajax call // save response returnedData.push(response); // see if we''re done with the last ajax call --ajaxCallsRemaining; if (ajaxCallsRemaining <= 0) { // all data is here now // look through the returnedData and do whatever processing // you want on it right here } }); }

Nota: el manejo de errores es importante aquí (no se muestra porque es específico de cómo estás haciendo tus llamadas ajax). Deberá pensar en cómo manejará el caso cuando una llamada ajax nunca se complete, ya sea con un error o se quede atascada durante mucho tiempo o se agote después de un tiempo prolongado.

jQuery Promises

Agregando a mi respuesta en 2014. En estos días, las promesas a menudo se usan para resolver este tipo de problema ya que $.ajax() jQuery ya devuelve una promesa y $.when() le permitirá saber cuándo se resuelven un grupo de promesas y recogerá los resultados de devolución para usted:

var promises = []; for (var i = 0; i < 10; i++) { promises.push($.ajax(...)); } $.when.apply($, promises).then(function() { // returned data is in arguments[0][0], arguments[1][0], ... arguments[9][0] // you can process it here }, function() { // error occurred });

Promesas estándar ES6

Como se especifica en la respuesta de kba : si tienes un entorno con promesas nativas incorporadas (navegador moderno o node.js o usando babeljs transpile o usando un pliegue potencial prometedor), entonces puedes usar promesas especificadas por ES6. Consulte esta tabla para obtener ayuda con el navegador. Las promesas son compatibles en casi todos los navegadores actuales, excepto IE.

Si doAjax() devuelve una promesa, puede hacer esto:

var promises = []; for (var i = 0; i < 10; i++) { promises.push(doAjax(...)); } Promise.all(promises).then(function() { // returned data is in arguments[0], arguments[1], ... arguments[n] // you can process it here }, function(err) { // error occurred });

Si necesita convertir una operación asincrónica no prometedora en una que devuelva una promesa, puede "promisificarla" así:

function doAjax(...) { return new Promise(function(resolve, reject) { someAsyncOperation(..., function(err, result) { if (err) return reject(err); resolve(result); }); }); }

Y, luego usa el patrón de arriba:

var promises = []; for (var i = 0; i < 10; i++) { promises.push(doAjax(...)); } Promise.all(promises).then(function() { // returned data is in arguments[0], arguments[1], ... arguments[n] // you can process it here }, function(err) { // error occurred });

Bluebird Promises

Si usa una biblioteca con muchas más funciones, como la biblioteca de promesas de Bluebird , entonces tiene algunas funciones adicionales integradas para facilitar esto:

var doAjax = Promise.promisify(someAsync); var someData = [...] Promise.map(someData, doAjax).then(function(results) { // all ajax results here }, function(err) { // some error here });


Puede usar el objeto Deferred de jQuery junto con el método when .

deferredArray = []; forloop { deferred = new $.Deferred(); ajaxCall(function() { deferred.resolve(); } deferredArray.push(deferred); } $.when(deferredArray, function() { //this code is called after all the ajax calls are done });


Puedes emularlo así:

countDownLatch = { count: 0, check: function() { this.count--; if (this.count == 0) this.calculate(); }, calculate: function() {...} };

entonces cada llamada asincrónica hace esto:

countDownLatch.count++;

mientras que en cada llamada de Asynch al final del método agrega esta línea:

countDownLatch.check();

En otras palabras, emula una funcionalidad de conteo regresivo.


Use una biblioteca de control de flujo como after

after.map(array, function (value, done) { // do something async setTimeout(function () { // do something with the value done(null, value * 2) }, 10) }, function (err, mappedArray) { // all done, continue here console.log(mappedArray) })


Verificación desde 2015: ahora tenemos promesas nativas en el navegador más reciente (Edge 12, Firefox 40, Chrome 43, Safari 8, Opera 32 y Android 4.4.4 y iOS Safari 8.4, pero no Internet Explorer, Opera Mini y versiones anteriores de Android).

Si queremos realizar 10 acciones asíncronas y recibir notificaciones cuando todas hayan finalizado, podemos utilizar Promise.all nativo, sin ninguna biblioteca externa:

function asyncAction(i) { return new Promise(function(resolve, reject) { var result = calculateResult(); if (result.hasError()) { return reject(result.error); } return resolve(result); }); } var promises = []; for (var i=0; i < 10; i++) { promises.push(asyncAction(i)); } Promise.all(promises).then(function AcceptHandler(results) { handleResults(results), }, function ErrorHandler(error) { handleError(error); });