【问题标题】:Promise.all causes Jest to display UnhandledPromiseRejectionWarningPromise.all 导致 Jest 显示 UnhandledPromiseRejectionWarning
【发布时间】:2019-02-22 11:46:27
【问题描述】:

我有一些调用 Promise.all 的代码。它在浏览器中运行正常,在控制台中没有警告。

有 3 个函数 f1、f2 和 f3,它们都返回一个 Promise。代码是这样的

Promise.all([
  f1(),
  f2(),
  f3()
]).then((values) => {
  resolve({success: true})
}).catch(err => {
  reject(err)
})

当我使用 Jest 测试包含上述代码的文件时,我看到了这个错误。

(node:17177) UnhandledPromiseRejectionWarning:未处理的承诺拒绝。此错误源于在没有 catch 块的情况下抛出异步函数内部,或拒绝未使用 .catch() 处理的承诺。 (拒绝编号:18)

这是对上述代码的错误编码方式还是 Jest 中的错误?

这是我正在使用的实际代码:

getDataFromDatabase() {
  return new Promise((resolve, reject) => {
    const assessmentUrl = `${this.assessmentUrl}`
    http.get(assessmentUrl).then(response => {
      if (response.data.record === null) {
        Promise.all([
          this._getPupilPlacement(),
          this._getSurveyQuestions(),
          this._getCompetencies()
        ]).then((values) => {
          successState.pupilPlacement = values[0].pupilPlacement
          successState.items = values[1].items
          successState.formid = values[2].formid
          successState.competencies = values[3].competencies
          const panels = this.getPanels(values[3].competencies)
          successState.panels = panels
          successState.numPages = panels.length
          successState.itemsAreOverridden = true
          resolve(successState)
        }).catch(err => {
          reject(err)
        })

      }
      else {
        resolve(response.data.record)
      }
    })
  })
}

【问题讨论】:

  • 您的 resolvereject 是来自承诺的回调。该承诺是否有 .catch()
  • @kemicofa 是的 - 该代码在一个函数中调用,该函数本身返回一个承诺,因此调用解析和拒绝。
  • 你能分享整个函数吗?
  • @kemicofa - 我刚刚发布了上面的完整代码。
  • 能否也分享一下测试的代码?很有可能您在测试用例中没有.catch() 拒绝

标签: javascript


【解决方案1】:

避免使用Promise constructor antipattern!您忘记处理来自 http.get(assessmentUrl) 承诺的错误。

你应该写

getDataFromDatabase() {
  const assessmentUrl = `${this.assessmentUrl}`
  return http.get(assessmentUrl).then(response => {
//^^^^^^
    if (response.data.record !== null)
      return response.data.record;
    return Promise.all([
//  ^^^^^^
      this._getPupilPlacement(),
      this._getSurveyQuestions(),
      this._getCompetencies()
    ]).then(values => {
      const panels = this.getPanels(values[3].competencies)
      return {
//    ^^^^^^
        pupilPlacement: values[0].pupilPlacement,
        items: values[1].items,
        formid: values[2].formid,
        competencies: values[3].competencies,
        panels: panels,
        numPages: panels.length,
        itemsAreOverridden: true,
      };
    });
  });
}

【讨论】:

    【解决方案2】:

    解释:

    调用reject 将引发错误。如果您的顶级承诺没有抓住它,那么这是一个未处理的承诺。

    MDN Image src

    解决方案:

    getDataFromDatabase().catch(err=>console.lor(err.message));
    

    拒绝的承诺示例:

    function getDataFromDatabase(){
      return Promise.reject(123);
    }
    
    getDataFromDatabase()
    .then(data=>console.log("Success " + data))
    .catch(err=>console.log("Error " + err));

    Promise MDN doc

    未来推荐:

    对于每个孩子的承诺,您似乎都在添加一个不需要的.catch()。只要在更高的地方有catch,那么promise就会被处理。

    【讨论】:

      猜你喜欢
      • 2021-10-22
      • 1970-01-01
      • 2021-05-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-20
      相关资源
      最近更新 更多