Javascript 为什么Q.all是这样实现的?

Javascript 为什么Q.all是这样实现的?,javascript,q,Javascript,Q,我假设Q.all([p1,p2,p3]),那么(f)与 p1.then(function () { p2.then(function () { p3.then(f); }); }); p1.then(function () { p2.then(function () { p3.then(f); }); }); 因为当创建了p1、p2和p3时,异步调用已经完成,我们只需等待它们全部解决,顺序无关紧要 我说得对吗 如果是的话,我一直

我假设
Q.all([p1,p2,p3]),那么(f)

p1.then(function () {
    p2.then(function () {
        p3.then(f);
    });
});
p1.then(function () {
    p2.then(function () {
        p3.then(f);
    });
});
因为当创建了
p1
p2
p3
时,异步调用已经完成,我们只需等待它们全部解决,顺序无关紧要

我说得对吗

如果是的话,我一直在看。我认为会是类似的(使用
然后
链接承诺)。但我发现它的实现方式完全不同?为什么呢

编辑:

让我更清楚一点。假设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毫秒就可以解决所有三个承诺。

不。他们是不同的

这里,您假设p2将仅在p1完成后启动。和p3仅在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完成后才开始发出请求或处理任何事情

希望我能回答你的问题:)

我假设
Q.all([p1,p2,p3]),那么(f)

p1.then(function () {
    p2.then(function () {
        p3.then(f);
    });
});
p1.then(function () {
    p2.then(function () {
        p3.then(f);
    });
});
不完全是
f
传递的是一组结果,您总是希望
返回
(承诺)结果;那么你会写信吗

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
在内部使用。

感谢您的回答,但我认为您的回答是错误的。我认为当我们有p1、p2和p3时,这意味着所有三个请求都已发送,我们只是在等待他们的响应。我们“等待”的顺序并不重要。这不像我们发送p1,等待响应然后再发送p2。@亚瑟:请注意,
p1
p2
p3
是承诺,而不是创建承诺的调用。没错!你的解释很好:)