我有一个数组的承诺应该并行运行,并尽快完成。我们有一个Promise.all(arrayOfPromises)
。但我想要一个修改过的承诺。所有这些都可以与动态数组一起工作。让我解释一下我的意思。
我从一个包含215个url (urlsArray
)的数组开始,我应该向其发送请求。但我一次只能处理100个请求。因此,我获取前100个url并创建包含这100个fetch的fetchArray
数组,然后将其传递给Promise.all(fetchArray)
。现在假设其中一个承诺解决了。我想把它从fetchArray
中移除,然后把第101次从urlsArray
中取出到fetchArray
中。我可以使用Promise.race()。但它会中断所有其他请求,所以我将失去所有的进程。这不是我想要的,因为我必须尽快得到所有215个url的响应。
在处理当前请求时,还可以将新的url添加到urlsArray
数组中。urlsArray
可能是无穷无尽的,新的url可以一次又一次地添加到数组中。所以fetchArray
应该用urlsArray
(如果有的话)一遍又一遍地替换刚刚解决的承诺,而不会丢失其他请求的进度。
有可能实现这个吗?你能给我一些想法,提示或代码吗?也许有一些关于如何实现这一点的文章或教程?
这样的代码应该可以工作:
(async() => {
const promises = []
// add 10 promises that will resolve between 1 and 4 seconds
for (let i = 0; i < 10; i += 1) {
addPromise(wait(Math.random() * 3000 + 1000))
}
while (promises.length) {
// wait for promise to resolve
const result = await Promise.race(promises.map(p => p.promise))
//remove resolved promise
promises.splice(promises.findIndex(p => p.id === result.id), 1)
console.log(result.val)
// add new promise
addPromise(wait(Math.random() * 3000 + 1000))
console.log('promises left', promises.length)
}
function addPromise(promise) {
const id = crypto.randomUUID()
const newPromise = promise.then(val => ({
id,
val
}))
promises.push({ id, promise: newPromise })
}
})()
// create a promise that resolves after some time
function wait(time) {
return new Promise(r => setTimeout(() => r(time), time))
}
虽然,我宁愿使用rxjs为这个