UnhandledPromiseRejectionWarning在异步等待诺言中

时间:2018-10-15 06:53:50

标签: javascript node.js

UnhandledPromiseRejectionWarning关于异步等待诺言

我有此代码:

function foo() {
  return new Promise((resolve, reject) => {
    db.foo.findOne({}, (err, docs) => {
      if (err || !docs) return reject();
      return resolve();
    });
  });
}

async function foobar() {
  await foo() ? console.log("Have foo") : console.log("Not have foo");
}

foobar();

其中的结果:

  

(节点:14843)UnhandledPromiseRejectionWarning:未处理的承诺拒绝(拒绝ID:1):错误

     

(节点:14843)[DEP0018] DeprecationWarning:已弃用未处理的承诺拒绝。将来,未处理的承诺拒绝将以非零退出代码终止Node.js进程。

注意:我知道我可以这样解决这个问题:

foo().then(() => {}).catch(() => {});

但是我们回到回调异步风格。

我们如何解决这个问题?

3 个答案:

答案 0 :(得分:2)

将代码包装在try-catch块中。

async function foobar() {
  try {
    await foo() ? console.log("Have foo") : console.log("Not have foo");
  }
  catch(e) {
    console.log('Catch an error: ', e)
  }
}

答案 1 :(得分:2)

then(() => {}).catch(() => {})是不需要的,因为catch不一定要紧跟then之后。

UnhandledPromiseRejectionWarning意味着一个诺言未与catch同步链接,这导致了未处理的拒绝。

async..await中,try..catch应该捕获错误:

async function foobar() {
  try {
    await foo() ? console.log("Have foo") : console.log("Not have foo");
  } catch (error) {
    console.error(error);
  }
}

另一种方法是在顶层处理错误。如果foobar是应用程序的入口点,并且不应链接到其他任何地方,则为:

foobar().catch(console.error);

foo的问题在于它没有提供有意义的错误。最好应该是:

if (err || !docs) return reject(err);

此外,大多数流行的基于回调的库都承诺会避免使用new Promisemongoist代表mongojs

答案 2 :(得分:1)

这里的每个解决方案都只会使错误消失,但您应该应该处理错误

如何处理它取决于错误以及所处应用程序的哪一部分。以下是一些示例。

您正在编写应用程序

如果您正在编写节点应用程序,但会抛出一些异常,则可能要使用process.exit(1)退出该应用程序并将错误显示给用户:

async function init() {
  await doSomethingSerious();
}

init().catch(error => {
  console.error(error);
  process.exit(1)
});

您正在编写一个模块

如果代码预期错误,则可以捕获该错误并将其用作值:

module.exports = async function doesPageExist(page) {
  try {
    await fetchPage(page);
    return true;
  } catch (error) {
    if (error.message === '404') {
      return false;
    }

    // Unrecognized error, throw it again
    throw error;
  }
}

请注意,如果此示例不是预期的错误,则会重新引发该错误。 很好。处理网络错误是最终用户的责任:

const doesPageExist = require('my-wonderful-page-checker');

async function init() {
  if (await doesPageExist('https://example.com/nope')) {
    console.log('All good')
  } else {
    console.log('Page is missing ?')
  }
}

// Just like before
init().catch(error => {
  console.error(error);
  process.exit(1)
});

您是用户

如果通过命令行使用预打包的应用程序(例如webpack或babel)时遇到此错误,则可能意味着该应用程序有错误,但未处理。这取决于应用程序或您的输入不正确。请参阅应用程序的手册。