如何在async函数中等待for循环内map生成的所有promise执行完毕?
问题解决方案
你现有代码的核心问题在于:account.map(async () => {}) 返回的是Promise数组,直接await一个Promise数组不会等待内部所有异步任务完成,只会把数组原样返回,所以你当前的写法等于没有等待axios请求执行,就会提前走到process.exit(0)逻辑。
下面提供两种常用实现方案,你可以根据业务需求选择:
方案1:串行批次执行(推荐)
每轮循环的请求全部完成后再进入下一轮循环,可以有效控制并发量,避免一次性请求过多触发接口限流、本地端口占满等问题。
async function function1(){ await mongoose.connect(CONNECTION_URL, { useNewUrlParser: true, useUnifiedTopology: true, }); for (let i=0; i<50; i++){ const account = await Account.find({ priority: { $lt: 50000 }, }) .skip(i * 1000) .limit(1000) .sort("priority"); // 等待当前批次所有axios请求完成 const batchPromises = account.map(async (item) => { // 此处写你的axios请求逻辑 }) // 如果你需要请求全部成功才继续,可替换为await Promise.all(batchPromises) await Promise.allSettled(batchPromises) } // 此时所有循环内的请求都已执行完成 process.exit(0) }
方案2:全量并行执行
所有批次的请求同时发起,最后统一等待全部完成,执行速度更快,但请求量较大时容易出现异常。
async function function1(){ await mongoose.connect(CONNECTION_URL, { useNewUrlParser: true, useUnifiedTopology: true, }); // 收集所有请求的Promise实例 const allPromises = [] for (let i=0; i<50; i++){ const account = await Account.find({ priority: { $lt: 50000 }, }) .skip(i * 1000) .limit(1000) .sort("priority"); const batchPromises = account.map(async (item) => { // 此处写你的axios请求逻辑 }) allPromises.push(...batchPromises) } // 等待所有批次的所有请求全部完成 await Promise.allSettled(allPromises) process.exit(0) }
提示:如果你的业务要求只要有一个请求失败就终止后续逻辑,把代码中的Promise.allSettled替换为Promise.all即可。
内容的提问来源于stack exchange,提问作者Rane
相关产品推荐
相关产品推荐

