有一个代码是从这里获取的:
var f1 = function() {
return new Promise(function(resolve) {
setTimeout(function() {
console.log(1);
resolve();
}, 1000);
});
}
var f2 = function() {
return new Promise(function(resolve) {
setTimeout(function() {
console.log(2);
resolve();
}, 2000);
});
}
var f3 = function() {
return new Promise(function(resolve) {
setTimeout(function() {
console.log(3);
resolve();
}, 3000);
});
}
var seqRunner = function(deeds) {
return deeds.reduce(function(p, deed) {
return p.then(deed);
}, Promise.resolve());
}
seqRunner([f1, f2, f3]).then(function() {
console.log('Done!');
});;
请向我解释一下,我根本不明白:为什么seqRunner函数应该返回一个空的承诺,目的是什么?
据了解,所有队列执行完毕后deeds,调用Promise.resolve()外层队列执行.then命令输出到控制台Done!。这很清楚。但我认为如果我最后删除它
.then(function() {
console.log('Done!');
});;
而且, Promise.resolve()),队列也可以正常工作。
天知道,我不明白承诺。为什么 this, Promise.resolve())在函数 return 中seqRunner?
你为什么不能这样做:
var seqRunner = function(deeds) {
return deeds.reduce(function(p, deed) {
return p.then(deed);
};
}
seqRunner([f1, f2, f3]);
你认为 reduce 函数的第二个参数是链中的最后一个承诺是错误的。如果你看看这个函数做了什么,你会发现这是第一个承诺,初始值!
执行过程中的构建
[f1, f2, f3].reduce((p, deed) => p.then(deed), Promise.resolve())是这样打开的:从这里删除初始值并不是那么容易。如果你手写调用链,你可能会这样写:
请注意,序列现在是非均匀处理的。要在数组上使用 reduce 达到相同的效果,您必须首先切断它的第一个元素并单独处理它:
如您所见,代码并没有变得更简单,反而变得更复杂了。此外,它变得更糟了- 其中出现了错误:
f1()抛出异常,那么旧代码会捕获它并将其存储在 promise 中,就像任何其他方法一样。新代码将在调用堆栈的更上层抛出来自 f1 的异常;seqRunner([f1, f2, f3])这不是问题——但如果你在存储数组上调用它,就会有惊喜。在不修改数组的情况下工作会更加困难;Promise.resolve(),新代码至少需要 1 个元素。PS 这是正确的代码,没有新语法中的这些错误:
如您所见,开始
Promise.resolve()要容易得多。在遍历带有结果累加的数组时选择“空”初始值是一般规则。所以,数组成员求和时,从0开始求和,查找数组中的最小数时,从无穷大开始,异步方法的顺序执行是从 开始
Promise.resolve()。因为它更容易,更漂亮。你所有的推论都是基于错误的前提:
这不是真的。
通过将第二个参数传递给方法
Array.prototype.reduce,您可以将其值用作累加器的初始值。这是一个简单的例子:在您的情况下,您需要将初始值设置为
Promise.resolve以启动承诺履行链。设计:
相当于
因此,在链的开头使用 Promise 以外的任何东西都会使其无效。