gpt4 book ai didi

javascript - 使用 forEach 和 async/await,对于 Node 和 Jest 的行为不同

转载 作者:太空宇宙 更新时间:2023-11-04 02:51:54 27 4
gpt4 key购买 nike

我有一个将数据写入 mongodb 的函数,如下所示:

const writeToDB = async (db, data) => {
const dataKeys = Object.keys(data)
dataKeys.forEach(async key => db.collection(key).insertMany(data[key]))
}

如果我在 Node 脚本中运行它,效果很好。但是当我尝试在 Jest 的 beforeAll 中使用它时,我从 Jest 收到了这个异步错误:

Jest did not exit one second after the test run has completed. This usually means that there are asynchronous operations that weren't stopped in your tests.

经过一些故障排除后,我发现 forEach 导致了问题。使用 for 循环解决了这个问题:

const writeToDB = async (db, data) => {
const dataKeys = Object.keys(data)
for (const key of dataKeys) {
await db.collection(key).insertMany(data[key])
}
}

搜索这个问题时我发现了这篇文章: https://codeburst.io/javascript-async-await-with-foreach-b6ba62bbf404

那里的解释很有道理,但它给我留下了一些疑问:

  • 根据这篇文章,即使在 Node 中它也不应该起作用脚本。怎么会这样?
  • 为什么在 Node 中执行它与在 Jest 中运行它不同?

编辑

读完所有评论后,我意识到我的第一个问题有点无稽之谈。通常我将异步函数的结果分配给变量,如果我不放置等待,则会出现未定义的错误。但这里的情况并非如此,因此脚本正常退出,并且数据库写入在后台同时发生。

最佳答案

现有答案已经详细解释了为什么 forEach 不应该与 Promise 一起使用。 forEach 回调不会考虑返回的 promise 并破坏 promise 链。 async..await 需要与 for..of 一起使用来串行评估 Promise,或者与 Promise.allmap 一起使用来并行评估。

Jest 支持 Promise,并期望从异步函数(it 等)返回的 Promise 表示该函数中发生的异步过程已经结束。

一旦 Jest 完成测试,它就会检查是否存在阻止 Node 退出的打开句柄。由于 Jest 没有返回并链接 Promise,因此它们所代表的流程会阻止 Jest 完成测试流程。

此问题由上述错误消息表示:

Jest did not exit one second after the test run has completed.

This usually means that there are asynchronous operations that weren't stopped in your tests. Consider running Jest with --detectOpenHandles to troubleshoot this issue.

关于javascript - 使用 forEach 和 async/await,对于 Node 和 Jest 的行为不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54751181/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com