如何在异步循环中保留数组的值? 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 推荐的方法。否则,我的建议在性能方面会更好。
我有下面的代码使用 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 推荐的方法。否则,我的建议在性能方面会更好。