为什么此代码可以完美运行?我不知道为什么此代码有效。
循环方法不返回任何内容,因此累加器必须为null,并且此代码不能正常工作。
const arr = [1, 2, 3, 4];
const awaitFunc = (val) => new Promise(function (resolve, reject) {
setTimeout(function () {
console.log('awaitFunc', val);
resolve();
}, 500);
});
const start = async () => {
console.log('start');
await arr.reduce(async (promise, val, index) => {
await promise;
console.log('reduce loop', val);
await awaitFunc(val);
}, Promise.resolve());
console.log('end');
};
start();
结果似乎是这样。
start
reduce loop 1
(500ms)
awaitFunc 1
reduce loop 2
(500ms)
awaitFunc 2
reduce loop 3
(500ms)
awaitFunc 3
reduce loop 4
(500ms)
awaitFunc 4
end
答案 0 :(得分:1)
一个async
函数会自动返回一个Promise。如果函数包含await
,则所有await
完成后,Promise便会解析(并且解释器到达功能块的底部)。由于累加器是async
函数,它会自动返回一个Promise,因此await
会计算 last 迭代(累加器的最后一次运行)返回的Promise的分辨率。有道理。
所以
await arr.reduce(async (promise, val, index) => {
await promise;
console.log('reduce loop', val);
await awaitFunc(val);
}, Promise.resolve());
等同于
await arr.reduce((promise, val, index) => {
return promise.then(() => {
console.log('reduce loop', val);
return awaitFunc(val);
// ^^^^^^^ returned end of Promise chain, so accumulator promise in next reduce loop will resolve
// once above promise resolves
});
}, Promise.resolve());
或
await arr.reduce((promise, val, index) => {
// just for illustration, don't use the explicit Promise construction antipattern
return new Promise((resolve) => {
// await promise;
promise.then(() => {
console.log('reduce loop', val);
// await awaitFunc(val);
awaitFunc(val).then(resolve)
// ^^^^^^^ Accumulator promise in next reduce loop will resolve
});
});
}, Promise.resolve());
const arr = [1, 2, 3, 4];
const awaitFunc = (val) => new Promise(function (resolve, reject) {
setTimeout(function () {
console.log('awaitFunc', val);
resolve();
}, 500);
});
const start = async () => {
console.log('start');
await arr.reduce((promise, val, index) => {
// just for illustration, don't use the explicit Promise construction antipattern
return new Promise((resolve) => {
// await promise;
promise.then(() => {
console.log('reduce loop', val);
// await awaitFunc(val);
awaitFunc(val).then(resolve)
});
});
}, Promise.resolve());
console.log('end');
};
start();