我有一个将数据写入 mongodb 的函数,如下所示:
const writeToDB = async (db, data) => {
const dataKeys = Object.keys(data)
dataKeys.forEach(async key => db.collection(key).insertMany(data[key]))
}
如果我在节点脚本中运行它,效果很好。但是当我尝试在 Jest 中使用它时beforeAll
我从 Jest 收到这个异步错误:
测试运行完成后,Jest 一秒钟都没有退出。这
通常意味着存在未发生的异步操作
在你的测试中停止了。
经过一些故障排除后我发现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 https://codeburst.io/javascript-async-await-with-foreach-b6ba62bbf404
那里的解释很有道理,但它给我留下了一些疑问:
- 根据这篇文章,即使在节点中它也不应该起作用
脚本。怎么就这样了?
- 为什么在 Node 中执行它与在 Jest 中运行它不同?
edit
读完所有评论后,我意识到我的第一个问题有点无稽之谈。通常我将异步函数的结果分配给变量,如果我不放置等待,则会出现未定义的错误。但这里的情况并非如此,因此脚本正常退出,并且数据库写入在后台同时发生。
现有答案已经详细解释了原因forEach
不应该以它的使用方式与 Promise 一起使用。forEach
回调不考虑返回的承诺并破坏承诺链。async..await
需要与使用for..of
评估一系列的承诺或与Promise.all
and map
并行评估。
Jest 支持 Promise 并期望从异步函数返回的 Promise (it
等)表示该函数中发生的异步进程已经结束。
一旦 Jest 完成测试,它就会检查是否存在阻止 Node 退出的打开句柄。由于 Jest 没有返回并链接 Promise,因此它们所代表的流程会阻止 Jest 完成测试流程。
该问题由上述错误消息表示:
测试运行完成后,Jest 一秒钟都没有退出。
这通常意味着存在未完成的异步操作
在你的测试中停止了。考虑使用 --detectOpenHandles 运行 Jest
来解决此问题。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)