每当您看到Promise.all()被使用时,通常将其与两个循环一起使用,如何将其变成一个而没有使用异步和维护执行顺序 >?
问题不是顺序,我知道promise.all都保留顺序,问题是关于只需要返回值时如何避免两个循环
function timeout(x){
return new Promise( resolve => {
setTimeout( () => {
return resolve(x);
},x)
})
}
const promises = [];
const results = [];
//First loop, array creation
for (i = 0; i < 20; i++) {
const promise = timeout(i*100)
promises.push(promise);
}
Promise.all(promises).then( resolvedP => {
//Second loop, async result handling
resolvedP.forEach( (timeout,i) => {
results.push({
index : i,
timeout : timeout
})
})
console.log(results);
})
//End of code
现在,可以使用async
解决此问题,但是在我的上下文中,我无法使用它,例如:
//Only one loop
for (i = 0; i < 20; i++) {
const timeoutAwait = await timeout(i*100);
results.push({
index : i,
timeout : timeoutAwait
})
}
console.log(results)
//End of code
以下是我尝试过的内容,但是没有使用resolve
时,promise不会返回.then()
值:
for (i = 0; i < 20; i++) {
const promise = timeout(i*100)
promises.push(promise);
results.push({index : i, timeout : promise});
}
Promise.all(promises).then( resolvedP => {
resolvedP.forEach( (timeout,i) => {
results.push({
index : i,
timeout : timeout
})
})
console.log(results);
//results[0].timeout is a Promise object instead of 0
})
//End of code
那么,有什么方法可以使我的第一个代码样本仅在一个循环中进行?请忽略上下文,仅是示例。
答案 0 :(得分:1)
function timeout(x) {
return new Promise(resolve => {
setTimeout(() => {
return resolve(x);
}, x);
});
}
const promises = [];
const results = [];
//First loop, array creation
for (let i = 0; i < 20; i++) {
const promise = timeout(i * 100).then(x => results.push({
index: i,
timeout: x
}));
promises.push(promise);
}
Promise.all(promises).then(() => {
console.log(results);
});
如果要保留执行/结果订单,请使用i
索引而不是.push
分配结果
const promise = timeout(i * 100).then(x => results[i] = {
index: i,
timeout: x
});
答案 1 :(得分:1)
与Promise.all
documentation一样,订单将被保留。它说明了返回值:
在所有其他情况下的待定承诺。然后,这个返回的承诺 异步解决/拒绝(堆栈为空时) 给定迭代中的所有诺言都已解决,或者 承诺拒绝。请参阅有关“异步性或 Promise.all的同步性”。返回的值将按顺序排列 不论完成顺序如何,都可以通过。
(由我突出显示。)
答案 2 :(得分:0)
如果您映射到值的数组而不是循环,我会更容易理解
const timeout = x=>Promise.resolve(x);
Promise.all(
[...new Array(3).keys()]//array [0,1,2]
.map(x=>timeout(x*100))//[timeout(0*100),timeout(1*100),...
).then(
result=>result.map(//results of the timeout, map to object
(timeout,index)=>({
index,
timeout
})
)
).then(
result=>console.log('result:',result)
)
异步更改共享变量(结果数组)通常不是一个好主意。只需解决承诺,并在最后一个.then
中创建所需的结果,现在您的承诺就可以解决为您想要的值。