目前,我有一个代码,该代码必须遍历数组并为每个交互请求一个API。
看起来像这样
let arrayOfIds = [1, 2, 3, 5, 8, 13, 21];
let order = []
let count = 0;
for (let id of arrayOfIds) {
asyncAPICall(id)
.then((result) => {
order.push(count++);
});
}
问题是是否保证在count++
数组中推入的order
总是 将是[0, 1, 2, 3, 4, 5, 6]
(以正确的升序排列) ?
我已经测试过几次了,但是我没有足够的信心在生产中使用它。
我也进行了搜索,但是我发现大多数是其他语言的,所以不能直接回答我的问题。
谢谢!
其他问题:
我该怎么做才能确保顺序正常?
答案 0 :(得分:2)
否不能保证您的请求将按照严格的顺序得到解决。
您的代码能够正常工作的原因是,您的请求得到解决时,您正在增加count
变量。因此,对于您而言,解决哪个请求都没关系-结果将相同(计数++)。
尝试使用order.push(count++);
代替console.log(result)
。
答案 1 :(得分:1)
不,它们是按顺序发送的,但是由于它们是异步的,因此它们可能会无序响应。
答案 2 :(得分:1)
如果您要保证兑现承诺,可以使用Promise.all
我已经相应地重写了代码,但有一点副作用,控制台在迭代过程中会记录数组值,以便您可以在控制台中查看运行顺序。
我为您的asyncAPICall创建了一个新的承诺来表示它。请注意,resolve参数是成功承诺的返回值。
Promise的唯一陷阱是,如果其中一个承诺失败,整个链条都会失败,这有很多解决方法,但这就是整个“另一个故事”
let arrayOfIds = [1, 2, 3, 5, 8, 13, 21];
let order = []
let count = 0;
const asyncAPICall = (i) => new Promise ((resolve, fail) => {
console.log("i am a new promise", i)
resolve(order.push(count++))
})
const allPromises = arrayOfIds.map(arrayValue => asyncAPICall(arrayValue))
Promise.all(allPromises)
.then((newArray) => console.log(newArray))
.catch((e) => console.log('something has gone wrong', e))
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all