function timeout(delay) {
return new Promise((resolve, reject) => {
setTimeout(resolve, delay);
});
}
function printDots(delays) {
return delays.map((delay) => {
return timeout(delay).then(() => process.stdout.write('.'))
}).reduce((acc, prom) => acc.then(prom));
}
printDots([513, 3402, 1337, 4122]).then(() => process.stdout.write('DONE!'));
这会打印.DONE!...
,但我预计会打印....DONE!
答案 0 :(得分:2)
。然后期望一个函数作为它的参数(onFullfilled, onRejected)
,任何不是函数的值完全忽略
但是,reduce回调中的prom
是一个承诺,所以只有第一个承诺会被等待
简单的更改,下面标记应该解决问题
function timeout(delay) {
return new Promise((resolve, reject) => {
setTimeout(resolve, delay);
});
}
function printDots(delays) {
return delays.map((delay) => {
return timeout(delay).then(() => process.stdout.write('.'))
}).reduce((acc, prom) => acc.then(() => prom));
// ^^^^^^
}
printDots([513, 3402, 1337, 4122]).then(() => process.stdout.write('DONE!'));
但是,请注意,承诺将在大约同一时间开始,不等待0到1开始之前结束等等
鉴于此,对于printDots来说,更好的解决方案是使用Promise.all
function printDots(delays) {
return Promise.all(delays.map((delay) => timeout(delay).then(() => process.stdout.write('.'))));
}
根据评论,承诺需要按顺序运行 - 这很简单,只需使用reduce
function timeout(delay) {
return new Promise((resolve, reject) => {
setTimeout(resolve, delay);
});
}
function printDots(delays) {
return delays.reduce((acc, delay) => acc.then(() => timeout(delay).then(() => process.stdout.write('.'))), Promise.resolve());
}
printDots([513, 3402, 1337, 4122]).then(() => process.stdout.write('DONE!'));
在这种情况下,您需要提供一个初始承诺(Promise.resolve)来减少,以便第一次迭代使用承诺,就像所有后续的承诺一样