知道.each()启动的所有异步调用何时执行完毕

Know when all async calls initiated by .each() are done executing

本文关键字:调用 异步 何时 执行 each 启动 知道      更新时间:2023-09-26

我正在使用node.js构建一些东西,并使用jQuery .each()循环遍历所有img标记。在所有回调.each()初始化完成后,我将在foo中获得所需的值。

var foo = -1;
window.each(function() {
  // abracadabra
  if (baz) foo = bar;
});
return foo; // this returns the incorrect foo as not all callbacks are complete

我该如何解决这个问题?

编辑

一种方法是有一个无限循环,不断检查回调的计数,当所有回调都完成时,返回foo。我觉得这有点怪,还有更好的吗?

var allCallbacksDone = false;
var foo = -1;
window.each(function(index, element) {
  // abracadabra
  if (baz) foo = bar;
  if (index == window.length - 1) allCallbacksDone = true;
});
while (!allCallbacksDone) {
  continue;
}
return foo;

第二次编辑

abracadabra是下载异步远程映像的GET请求。

不能从依赖异步调用结果的函数返回值

很抱歉有人大喊大叫,但不得不说。。。

您能做的最好的事情是在完成所有其他回调后调用另一个回调。

任何其他操作都将导致繁忙循环。,这将使应用程序没有响应。

要解决此问题(并非双关语),请使用jQuery的deferred对象:

var defArray = [];
window.each(function(index, element) {
    // create a deferred object and store it
    var d = $.Deferred();
    defArray.push(d);
    // trigger the image download 
    however you do it...
    // register a callback for the download completion
    // which "resolves" the deferred object
    someimg.onload = function() {
        d.resolve();
        // probably other actions needed here too
    }        
});
// now call _another_ function once _all_ of the deferreds are resolved
$.when.apply($, defArray).then(function() {
    // everything is done - do your calculations
});

请注意,我的第一行仍然有效——你不能只是等待一切,然后返回结果——JS不是这样工作的。

理想情况下,您将创建一个添加延迟对象,并且您的函数基于该对象返回一个promise,您的最终回调将resolve与最终计算的结果一起返回。

试试这个。。。

var foo = -1;  // Don't need this now
var count = window.length;
window.each(function() {
  // abracadabra
  count--;
  if (count == 0) complete(bar);
});
function complete(value) {
//  everything is complete and value == bar
}

试试这个:

function check(callback) {
  var foo = -1, complete = false, count = window.length - 1, interval;
  window.each(function (index) {
    if (baz) foo = bar;
    complete = (index == count);
  });
  interval = setInterval(function () {
    if (complete) {
      clearInterval(interval);
      callback();
    }
  }, 20);
}

调用check()来运行.each()循环,为任务完成时提供一个方法callback