我正在尝试实现一个获取图像的承诺队列。因此,我创建了一个包含 3 个 Promise 的数组,并使用
Promise.any()
获取第一个获取的图像。但是当我收到第一张图像时,我想用新的承诺替换旧的承诺。示例:
const images = [
fetch("some/image"),
fetch("another/image"),
fetch("another/image"),
];
Promise.any(images).then(img => {
images[n] = fetch("another/image") // if only I knew "n"
return img
}).then(/*whatever*/)
我尝试通过将数组的每个 Promise 与
Promise.any
返回的 Promise 进行比较来查找索引,但这不起作用,因为它返回了一个新的 Promise。
那么,我如何知道
Promise.any
的promise返回的promise的索引呢?
您可以在将每个图像承诺传递给
Promise.any
之前添加索引(添加.then
链)
const images = [
Promise.resolve("some/image1"),
Promise.resolve("some/image2"),
Promise.resolve("some/image3"),
];
Promise.any(images.map((p, i) => p.then(v => [v, i]))).then(([img, index]) => {
console.log('image', img)
console.log('index', index)
})
考虑使用 promise-limit 包来实现此目的。它可以让您以更稳健的方式解决您的问题:
var promiseLimit = require('promise-limit')
var limit = promiseLimit(2) // max count of simultaneous requests
var allImages = ['a', 'b', 'c', 'd', 'e']
Promise.all(allImages.map((name) => {
return limit(() => fetch(name).then(imageLoadedCallback))
}))
这是我根据 @KiraLT 的答案使用的打字稿函数。
async function promiseAnyIndexed<T extends readonly unknown[] | []>(
values: T
): Promise<(Awaited<T[number]> | undefined)[]> {
const response = await Promise.any(values.map((promise, index) => promise.then((result) => ({ result, index }))))
const result = new Array(values.length)
result[response.index] = response.result
return result
}