【问题标题】:Know when all async calls initiated by .each() are done executing知道 .each() 发起的所有异步调用何时执行完毕
【发布时间】:2012-02-09 05:41:30
【问题描述】:

我正在使用 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。我觉得这有点hack-ish,会有更好的东西吗?

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 请求,用于下载异步的远程图像。

【问题讨论】:

  • 你在做什么导致回调?回调处理程序是一个单独的函数,可以异步运行。如果它只是你正在运行的“每个”,那么它在解析所有选定的元素之前不会退出。
  • 异步回调在哪里? .each 函数不是严格的回调,它只是一个函数引用。回调是一个稍后调用以响应某个事件的函数。
  • 重要的问题是abracadabra 是什么。如果它不是异步的,那么这里就没有异步发生。 each 是同步的。
  • @lonesomeday abracadabra 是下载远程图像的 GET 请求。
  • @lonesomeday:我早该指定的。太晚了,已经投了-1票。 :(

标签: javascript jquery node.js asynchronous callback


【解决方案1】:

试试这个...

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
}

【讨论】:

  • 我不想在一切都完成后设置foo。我想在所有回调完成后返回它。
  • 啊——我明白了。我会修改以适应。
  • 你能提供一个例子,而不仅仅是一个sn-p吗?我想我误解了这个问题。
  • 我们需要有关回调的信息。在不知道自己在做什么的情况下,无法给出示例代码。
  • .each()调用的匿名函数,这里叫回调吧?我指的是那个。
【解决方案2】:

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

对不起,大喊大叫,但不得不说......

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

其他任何事情都会导致繁忙的循环。这将使应用程序无响应。

要解决这个问题(不是双关语),请使用 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 与最终计算的结果。

【讨论】:

  • 匿名函数 jQuery .each() 调用有一个 GET 请求来下载异步的远程图像,对吧?我不知何故需要知道所有这些线程何时完成执行。然后我会知道页面上最大的图像。
  • 好吧,现在我们到了某个地方……我会修改的。
  • 我正在为 node.js 使用 imagemagick。图片下载后有回调。无法让它工作。
【解决方案3】:

试试这个:

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 方法。

【讨论】:

    猜你喜欢
    • 2019-09-14
    • 1970-01-01
    • 2016-12-14
    • 1970-01-01
    • 2018-05-07
    • 2020-01-15
    • 1970-01-01
    • 2017-06-23
    • 2014-03-22
    相关资源
    最近更新 更多