最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

使用forEach和asyncawait,节点和Jest的行为不同

运维笔记admin10浏览0评论

使用forEach和async / await,节点和Jest的行为不同

使用forEach和async / await,节点和Jest的行为不同

我有一个函数将数据写入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])
  }
}

搜索这个问题我遇到了这篇文章:

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

  • 根据这篇文章,它甚至不应该在节点脚本中工作。怎么回事呢?
  • 为什么在节点中执行它与在Jest中运行它不同?

编辑

在阅读完所有评论之后,我意识到我的第一个问题有点无稽之谈。通常我将异步函数的结果分配给变量,如果我没有等待,那么行下面会有一个未定义的错误。但这不是这种情况,因此脚本正常退出,db写入在后台同时发生。

回答如下:

现有的答案已经详细解释了为什么forEach不应该像使用它一样使用承诺。 forEach回调不会将退回的承诺考虑在内并打破承诺链。 async..await需要与for..of一起用于评估系列中的承诺,或与Promise.allmap进行并行评估。

Jest支持promises并期望从异步函数(it等)返回的promise表示此函数中发生的异步进程已结束。

一旦Jest完成测试,它会检查是否存在阻止Node退出的打开句柄。由于承诺没有被Jest返回和链接,它们所代表的流程阻止了Jest完成测试过程。

此错误消息表示此问题:

测试运行完成后,Jest没有退出一秒钟。

这通常意味着您的测试中没有停止异步操作。考虑使用--detectOpenHandles运行Jest来解决此问题。

发布评论

评论列表(0)

  1. 暂无评论