我正在致力于构建带有 setTimeouts 的 Promise 链。所有 Promise 都需要串联而不是并行运行。我正在使用 Bluebird 模块来实现 Promise 执行的串行流程。
有人可以解释一下为什么这段代码给我的输出是 1,2,3,4 而不是 4,3,2,1?
var bluebirdPromise = require('bluebird');
function p1(value) {
return new Promise(function(resolve, reject) {
setTimeout(function(resolve) {
console.log(value);
resolve;
}, value * 1000);
});
}
var arr = [p1(4), p1(3), p1(2), p1(1)];
bluebirdPromise.reduce(arr,
function(item, index, length) {
}).then(function (result) {
});
最佳答案
有几个问题:
您拥有的
console.log
并不依赖于之前已解决的 promise 。只有超时决定何时输出发生。当您在“同一”时间创建所有四个 Promise 时,因此所有四个setTimeout
调用都会同时调用,它们的回调将在确定的超时时调用。之后如何链接 Promise 并不重要...要解决这个问题,您需要将console.log
移动到then
回调中,因为该回调只会被执行当链中的前一个 promise 得到解决时。您的代码中未调用
resolve
函数。您需要添加括号。setTimeout
回调的解析参数隐藏了同名的real函数:您需要删除该参数。
这是建议的更正。对于此代码片段,我已将 bluebird reduce
替换为标准 Array#reduce
,但它的工作方式与 bluebird 的 reduce
类似:
function p1(value) {
return new Promise(function(resolve, reject) {
setTimeout(function() { // ***
resolve(value); // ***
}, value * 1000);
});
}
var arr = [p1(4), p1(3), p1(2), p1(1)];
arr.reduce(function(promise, next) {
return promise.then(_ => next).then( value => {
console.log(value); // ***
return value;
});
}, Promise.resolve());
关于JavaScript 串行 Promise 与 setTimeout,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43819894/