2014-11-08 98 views
2

我假设Q.all([p1, p2, p3]).then(f)是没有什么不同为什么Q.all像这样执行?

p1.then(function() { 
    p2.then(function() { 
     p3.then(f); 
    }); 
}); 

因为当p1p2p3创建的异步调用已经作出,我们只需要等待他们都解决和没有按顺序没关系。

我正确吗?

如果是这样,我一直在寻找kriskowal's all implementation。我认为这会是类似的事情(链接承诺使用then)。但我发现它的实施方式完全不同?这是为什么?

编辑:

让我更加清楚一点。说p1,p2,p3分别在100ms,200ms,300ms解析。等待他们的反应顺序不作任何differens

p1.then(function() { 
    // we're here at 100ms 
    p2.then(function() { 
     // 100ms later we're here 
     p3.then(f); // f gets called 100ms later (at 300ms) 
    }); 
}); 

p3.then(function() { 
    // we're here at 300ms 
    p2.then(function() { 
     // boom! resolves in a snap 
     p1.then(f); // f also gets called instantly (at 300ms) 
    }); 
}); 

在这两个例子中,我们只能等待所有三项承诺300ms的解决。

回答

4

我假设Q.all([p1, p2, p3]).then(f)是没有什么不同

p1.then(function() { 
    p2.then(function() { 
     p3.then(f); 
    }); 
}); 

不完全是。 f正在通过一系列结果,并且您总是希望return(承诺)结果;所以你会写

p1.then(function(r1) { 
    return p2.then(function(r1) { 
     return p3.then(function(r3) { 
      return f([r1, r2, r3]); 
     }); 
    }); 
}); 

// or equivalently, better matching a separate `Q.all`: 
p1.then(function(r1) { 
    return p2.then(function(r1) { 
     return p3.then(function(r3) { 
      return [r1, r2, r3]; 
     }); 
    }); 
}).then(f); 

因为当P1,P2和P3产生的异步调用已经 而做出的,我们只需要等待他们都解决和 为了不物。

我正确吗?

有点。的确,.all的天真版本可以像这样实施。然而,我们需要看一个重要的“边缘”情况:当承诺没有得到履行但被拒绝时。突然之间,回调的嵌套结构就变成了错误 - 因为我们想要平行并从头看所有三个承诺。假设p3在200ms后解析,p1在300ms后解析,p2在100ms后被拒绝。

使用嵌套的then回调函数,它会在第一次观察p2之前等待整个300ms(p1) - 但是,它早已被拒绝。相反,.all方法想要提前失败,并拒绝结果承诺,只要任何被拒绝。

因此(和一点性能),Q.all内部使用deferred pattern

0

没有。他们是不同的。

在这里,你认为p2只会在p1完成后才开始。并且p2只在p2完成之后。

p1.then(function() { 
    p2.then(function() { 
     p3.then(f); 
    }); 
}); 

所以基本上,你介绍了序列和依赖。做1,然后2,然后3.如果p3取决于p2的结果并且p2取决于p1的结果,则这是理想的。但是,这会给代码带来很多复杂性和依赖性,所以您最好谨慎使用它。甚至尽可能地避免它。

以下,但是,不需要序列:

Q.all([p1, p2, p3]).then(f) 

F由所有3是成品(P1,P2和P3),但有三者之间无交叉依赖性。 p2可能会先完成,然后是p1或p3(它们是异步完成的)。不需要订单。唯一的要求是所有三个都按照f的任何顺序完成。总的来说,如果可能的话,这会更好。 p2和p3不必等到p1完成后才开始发出请求或处理任何内容。

希望我回答你的问题:)

+1

谢谢你的回答,但我认为你错了。我认为,当我们有p1和p2以及p3时,意味着所有三个请求都已发送,我们只是在等待他们的回应。我们“等待”的顺序并不重要。这不像我们发送p1,等待响应,然后发送p2。 – adm 2014-11-08 11:44:50

+0

@Arthur:请注意'p1','p2','p3'是承诺,而不是创建承诺的调用。 – Bergi 2014-11-08 13:25:22

+0

真的!你的解释很棒:) – 2014-11-08 19:10:14