You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript中异步函数为何不等待Promise执行完成?

异步循环未等待导致执行顺序异常的问题分析与解决

问题根源

你在for...of循环中调用match异步函数时,没有使用await等待函数执行完成,导致循环会快速遍历所有searchCriterias,优先执行每个findOrCreate里的同步代码(前两个console.log),而所有异步的TenderAccount.findOne请求会被批量触发,等这些异步操作全部完成后,才会依次打印Doc的结果。

详细解释

异步函数的执行逻辑是:

  • async函数中,await之前的代码是同步执行的,遇到await时会暂停函数执行,让出JavaScript线程,等待异步操作完成后才继续执行后续代码。
  • 当你循环调用match(searchCriteria)却不加await时,每次调用都会立即执行match内的同步流程(调用findOrCreate并打印前两行日志),随后函数在await TenderAccount.findOne处暂停,循环直接进入下一次迭代,不会等待当前match的异步操作完成。
  • 最终所有同步日志先批量输出,等所有findOne异步请求完成后,才会依次输出Doc相关日志。

解决方案

修改循环逻辑,在调用match时添加await,确保每次迭代都等待当前异步函数执行完成后再进入下一次循环:

// 修正后的循环代码
for (const searchCriteria of searchCriterias) {
  await match(tender, searchCriteria); // 添加await等待异步函数完成
}

修改后控制台输出会符合预期的顺序:

Search Criteria Name: test-sc
Tender Name: test-tender
Doc: null
Search Criteria Name: test2-sc
Tender Name: test2-tender
Doc: null
Search Criteria Name: test3-sc
Tender Name: test3-tender
Doc: null

补充:并行执行场景(可选)

如果你的业务场景不需要严格按顺序处理每个searchCriteria,只是希望每个findOrCreate内部的日志顺序正确,可以使用Promise.all并行发起所有异步请求:

// 并行执行(日志仍会先批量输出同步部分,再输出异步结果,但每个findOrCreate内部逻辑不受影响)
await Promise.all(searchCriterias.map(searchCriteria => match(tender, searchCriteria)));

注:这种方式下同步日志还是会先全部打印,再打印所有异步结果,适合不需要顺序依赖的批量处理场景。

内容的提问来源于stack exchange,提问作者Julián Álvarez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 02:10:51