我假设Q.all([p1, p2, p3]).then(f)
与
p1.then(function () {
p2.then(function () {
p3.then(f);
});
});
因为当p1
,p2
和p3
创建时,异步调用已经完成,我们只需等待所有这些调用解决,订单无关紧要
我说错了吗?
如果是这样,我一直在关注kriskowal's all
implementation。我认为它会类似(使用then
链接承诺)。但我发现它的实现方式完全不同?那是为什么?
修改
让我更清楚一点。假设p1,p2,p3分别在100ms,200ms,300ms内解析。等待响应的顺序没有区别
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)
});
});
在这两个例子中,我们只等待300毫秒才能解决所有三个承诺。
答案 0 :(得分: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
回调,它会在第一次观察p1
之前等待整个300毫秒(p2
) - 但是,它早已被拒绝了。相反,.all
方法希望提前失败,并且只要任何传递的承诺被拒绝,就会拒绝结果承诺。
因此(以及一点性能),Q.all
在内部使用deferred pattern。
答案 1 :(得分:0)
不。他们是不同的。
在此,假设p2仅在p1完成后才开始。 p3完成后才进行p3。
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完成后才开始发出请求或处理任何内容。
希望我回答你的问题:)