我有几组承诺,如何解析每组 "sequentially"?
I have groups of promises, how do I resolve each group "sequentially"?
有一个图书馆叫做 p-limit that is built for this purpose, but it's written in ESM, so it's a hassle to deal with. I figured, how hard could it be to implement my own? So I came up with this implementation:
(async() => {
const promisedAxiosPosts = _.range(0, 100).map(async(item, index) => {
console.log(`${index}: starting`);
return Promise.resolve();
});
let i = 0;
for (const promisedAxiosPostGroup of _.chunk(promisedAxiosPosts, 10)) {
console.log(`***********************
GROUP ${i}
SIZE ${promisedAxiosPostGroup.length}
***********************`);
await Promise.all(promisedAxiosPostGroup);
i++;
}
}
)().catch((e) => {
throw e;
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js" integrity="sha512-WFN04846sdKMIP5LKNphMaWzU7YpMyCU245etK3g/2ARYbPK9Ub18eG+ljU96qKRCWh+quCY7yefSmlkQw1ANQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
为什么不等待每个块完成后再继续下一个块?
我认为 map
可能是罪魁祸首,但我不知道如何:它 returns 一个 Promise<void>[]
;如果它在函数上 await
ing,它不会返回 void[]
(不确定这是否是一回事)?
为此,您需要 return 一个函数,该函数在调用时 return 是一个承诺。函数(athunk)延迟实际动作的执行
数组分块后,调用当前块中的函数,使用Promise.all()
等待所有promise resolve:
(async() => {
const pendingPosts = _.range(0, 100).map((item, index) => {
return () => { // the thunk
console.log(`${index}: starting`);
// a simulation of the action - an api call for example
return new Promise(resolve => {
setTimeout(() => resolve(), index * 300);
});
}
});
let i = 0;
for (const pendingChunk of _.chunk(pendingPosts, 10)) {
console.log(`***********************
GROUP ${i}
SIZE ${pendingChunk.length}
***********************`);
await Promise.all(pendingChunk.map(p => p())); // invoke the thunk to call the action
i++;
}
}
)().catch((e) => {
throw e;
})
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js" integrity="sha512-WFN04846sdKMIP5LKNphMaWzU7YpMyCU245etK3g/2ARYbPK9Ub18eG+ljU96qKRCWh+quCY7yefSmlkQw1ANQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
有一个图书馆叫做 p-limit that is built for this purpose, but it's written in ESM, so it's a hassle to deal with. I figured, how hard could it be to implement my own? So I came up with this implementation:
(async() => {
const promisedAxiosPosts = _.range(0, 100).map(async(item, index) => {
console.log(`${index}: starting`);
return Promise.resolve();
});
let i = 0;
for (const promisedAxiosPostGroup of _.chunk(promisedAxiosPosts, 10)) {
console.log(`***********************
GROUP ${i}
SIZE ${promisedAxiosPostGroup.length}
***********************`);
await Promise.all(promisedAxiosPostGroup);
i++;
}
}
)().catch((e) => {
throw e;
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js" integrity="sha512-WFN04846sdKMIP5LKNphMaWzU7YpMyCU245etK3g/2ARYbPK9Ub18eG+ljU96qKRCWh+quCY7yefSmlkQw1ANQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
为什么不等待每个块完成后再继续下一个块?
我认为 map
可能是罪魁祸首,但我不知道如何:它 returns 一个 Promise<void>[]
;如果它在函数上 await
ing,它不会返回 void[]
(不确定这是否是一回事)?
为此,您需要 return 一个函数,该函数在调用时 return 是一个承诺。函数(athunk)延迟实际动作的执行
数组分块后,调用当前块中的函数,使用Promise.all()
等待所有promise resolve:
(async() => {
const pendingPosts = _.range(0, 100).map((item, index) => {
return () => { // the thunk
console.log(`${index}: starting`);
// a simulation of the action - an api call for example
return new Promise(resolve => {
setTimeout(() => resolve(), index * 300);
});
}
});
let i = 0;
for (const pendingChunk of _.chunk(pendingPosts, 10)) {
console.log(`***********************
GROUP ${i}
SIZE ${pendingChunk.length}
***********************`);
await Promise.all(pendingChunk.map(p => p())); // invoke the thunk to call the action
i++;
}
}
)().catch((e) => {
throw e;
})
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js" integrity="sha512-WFN04846sdKMIP5LKNphMaWzU7YpMyCU245etK3g/2ARYbPK9Ub18eG+ljU96qKRCWh+quCY7yefSmlkQw1ANQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>