等待多个延迟对象完成并使用已解析的值 [英] Waiting for multiple deferred objects to be finished and use the resolved values

查看:125
本文介绍了等待多个延迟对象完成并使用已解析的值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图想办法等待多个延迟对象并在完成后处理它们,可能就像为延迟对象开始下一组。

I am trying to figure out a way to wait for multiple deferred objects and process them once done, may be like to start next set for deferred objects.

I我被困了,因为以下的结果不是预期的结果。
我期待结果为

I am stuck because the result of the following is not the it is expected to be. I am expecting the result as

allDone resovled values are 1,2,3

实际结果是

allDone resovled values are 1,2



var dfd1 = new $.Deferred();
var dfd2 = new $.Deferred();
var dfd3 = new $.Deferred(); 
var dfds = [ dfd1, dfd2, dfd3 ]; 
var resolvedValues = [];

$.when.apply($, dfds).done(function() {     
    dfds.forEach(function(dfd){
        console.log("inloop");      
        dfd.promise().done(function(value) {
            resolvedValues.push(value);         
        });     
    });
    console.log("allDone resovled values are" + resolvedValues);
})

dfd1.resolve(1);
dfd2.resolve(2);
dfd3.resolve(3);


推荐答案

对于 why ,见下文。但是你过度复杂了。 :-)当你给出解析后的值作为参数时,你给出了从获得的最终承诺的回调:

For the why, see below. But you're overcomplicating it. :-) The callback you give the final promise you get from when gives you the resolved values as arguments:

$.when.apply($, dfds).done(function(a, b, c) {
  // Here, a is 1, b is 2, c is 3
  // Or you can access them on `arguments`
})

直播示例:

var dfd1 = new $.Deferred();
var dfd2 = new $.Deferred();
var dfd3 = new $.Deferred(); 
var dfds = [ dfd1, dfd2, dfd3 ]; 
var resolvedValues = [];

$.when.apply($, dfds).done(function() {
  // Use a trick to turn `arguments` into a real array
  var a = Array.prototype.slice.call(arguments);
  // Show what we got
  snippet.log("allDone: " + a.join(", "));
})

dfd1.resolve(1);
dfd2.resolve(2);
dfd3.resolve(3);

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="//tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

附注:我假设你正在处理一个数组故意。如果您需要等待固定数量的承诺,只需使用更简单的表格

Side note: I assume you're dealing with an array on purpose. If you have a fixed number of promises you need to wait on, just use the simpler form

$.when(dfd1, dfd2, dfd3).then(function(a, b, c) {
    // ...
});






这是为什么你得到你得到的非常奇怪的结果:jQuery的 Deferred / Promise 对象有问题,因为它们是 chaotic :当你对它们调用完成时,你不知道你的回调是否会同时执行 异步。这是一个严重的缺陷,一个真正的Promises / A +实现没有(回调总是异步)。


Here's why you're getting the very odd result you're getting: jQuery's Deferred/Promise objects have a problem in that they are chaotic: When you call done on them, you don't know whether your callback will be executed synchronously or asynchronously. This is a serious flaw, and one that a true Promises/A+ implementation does not have (the callback is always asynchronous).

jQuery将异步调用回调 如果承诺尚未解决。但如果已解决,它会将其称为同步

jQuery will call the callback asynchronously if the promise is not yet resolved. But it will call it synchronously if it isn't resolved:

var d1 = $.Deferred();
d1.done(function() {
    console.log("I'm called asynchronously");
});
d1.resolve();

var d2 = $.Deferred();
d2.resolve();
d2.done(function() {
    console.log("I'm called synchronously");
});

所以你的代码中发生的是整个已完成 c> c> c> c> c> c> c> c> c> c> c> c>已解决( dfd3 )。由于承诺未在 完成 c>完成回调之后标记已解决,因此当您的代码运行时, dfd1 dfd2 已解决,但 dfd3 仍在解决过程中。因此,对于 dfd1 dfd2 同步调用内部回调,但异步 dfd3 。因此,在将 dfd3 返回值推送到数组之前,您将输出结果。

So what's happening in your code is that the overall done callback that when fires is fired during the done callback on the last promise that got resolved (dfd3). Since the promise isn't marked resolved until after the done callbacks have been completed, when your code runs, dfd1 and dfd2 are resolved but dfd3 is still in the process of being resolved. So your inner callbacks are called synchronously for dfd1 and dfd2 but asynchronously for dfd3. So you're outputting your result before the dfd3 return value has been pushed onto your array.

这篇关于等待多个延迟对象完成并使用已解析的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆