如何在异步循环中保留数组的值? javascript

How to retain values of array inside async loop? javascript

我有下面的代码使用 api 来获取客户数据。问题是当循环转到第二个索引时,customerIds 确实保留了前一个 index 的值(请参阅下面的控制台日志)。

有人知道如何正确实现吗?


这是我的代码

let customerIds = [];

arrayChunks.forEach(async (chunkGroupIds, index) => {
    try {
        console.log('customerIds - before', index, customerIds)

        const checkStatusResult = await checkStatus(
            token,
            chunkGroupIds
        )

        chunkGroupIds.map((customerId) => {
            const found = checkStatusResult.response.data.find(
                (data) => customerId.toString() === data.customerId
            )

            if (found) {
                customerIds = [...customerIds, customerId]
            }
        })
        
        console.log('customerIds - after', index, customerIds)
    } catch (error) {
        ...
    }
})

console.log('customerIds - final', customerIds)

控制台日志:问题可以通过打印的文本来显示。正如我们所看到的,当它转到第二个索引时,它没有从索引 1 中获取先前的值。

customerIds - before 0 []
customerIds - after 0 [2,3,5]
customerIds - before 1 []
customerIds - after 1 []
... and so on

customerIds - final []

使用for of循环而不是回调方法

let customerIds = [];
let index = 0;

for (const chunkGroupIds of arrayChunks) {
    try {
        console.log('customerIds - before', index, customerIds)

        const checkStatusResult = await checkStatus(
            token,
            chunkGroupIds
        )

        chunkGroupIds.map((customerId) => {
            const found = checkStatusResult.response.data.find(
                (data) => customerId.toString() === data.customerId
            )

            if (found) {
                customerIds.push(customerId);
            }
        })
        
        console.log('customerIds - after', index, customerIds)
    } catch (error) {
        ...
    } finally {
       index++;
    }
}

console.log('customerIds - final', customerIds)

这似乎是一个异步问题,它可能看起来像数组 运行 中的 promise 是顺序的,但事实并非如此。在 forEach 循环中,所有这些都同时 运行ning。

这对您来说可能是个好事,因为您不必等待顺序时间的总和,而您可能正在苦苦挣扎的是在最后一部分,您希望看到包含所有附加值,为此我推荐以下内容:

const promises = arrayChunks.map(async (chunkGroupIds, index) => {
    try {
        console.log('customerIds - before', index, customerIds)

        const checkStatusResult = await checkStatus(
            token,
            chunkGroupIds
        )

        chunkGroupIds.map((customerId) => {
            const found = checkStatusResult.response.data.find(
                (data) => customerId.toString() === data.customerId
            )

            if (found) {
                customerIds = [...customerIds, customerId]
            }
        })
        
        console.log('customerIds - after', index, customerIds)
    } catch (error) {
        ...
    }
})

await Promise.all(promises); // Wait until all of them are finished
console.log('customerIds - final', customerIds)

在这里,Promise.all 实用程序允许您等到一组 promise 完成,由于 async 关键字,函数会自动映射到 promise。

如果您需要按顺序执行您的承诺,您可以使用@amir-saleem 推荐的方法。否则,我的建议在性能方面会更好。