处理 Js 承诺拒绝

Handling Js promise rejection

你如何处理承诺之外的错误(例如下面的"new error")?

function testError() {
    throw new Error("new error") // how to handle this?
    var p123 = new Promise(function(resolve, reject) {
         resolve(123)
    });
    return p123
};

testError().catch(err => {
        return err;  // code doesn't come here
    })
    .then(ok => {
        console.log(ok)
    });

如果您不确定某个函数是否会同步抛出(或 return 一个值),您可以使用 .then() 调用它。这将包装它,以便无论结果如何生成,结果都将得到一致的处理:

function testError() {
  throw new Error("new error") // how to handle this?
  var p123 = new Promise(function(resolve, reject) {
    resolve(123)
  });
  return p123
};

Promise.resolve()
  .then(testError)
  .catch(err => {
    console.error(err);
    return err; 
  })
  .then(ok => {
    console.log(ok.message)
  });

由于错误不涉及异步代码,因此常规 try-catch 在这里应该没问题:

try {
  testError().catch(err => {
    return err;  // code doesn't come here
  })
  .then(ok => {
     console.log(ok)
  });
}
catch(e) {
   // 
}

请注意,当 async-await 模式最终成为解决承诺的本机方式时,try-catch 也将成为处理错误的本机方式:

try {
    var ok = await testError();
    console.log(ok)
}
catch(e) {
    console.log('e:' +e);
}

可以很容易地验证,这个正确地处理了同步和异步错误,并且比 then-catch.

干净得多

由于错误是在 promise 之外抛出的,因此您无法使用 promise catch 语句捕获它。

您可以使用 try/catch 来捕获错误。

function testError() {
    throw new Error("new error") // how to handle this?
    var p123 = new Promise(function(resolve, reject) {
         resolve(123)
    });
    return p123
};

try {
  testError().then(ok => {
    console.log(ok)
  });
} catch (err) {
  console.log(err.message);
}

如果可以,请像这样重写 testError 函数

function testError () {
  return new Promise(function (resolve, reject) {
     throw new Error('new error')
     resolve(123)
  })
}

testError().then(ok => console.log(ok),
                 err => console.error(err.message))

  1. 运行 一次看到它在 console.error
  2. 中抛出错误
  3. 注释掉 throw 行以查看 promise 成功解析

你重写它,因为让调用者同时检查异常和拒绝是一种反模式:

function testError() {
  return Promise.resolve().then(() => {
    throw new Error("new error"); // rejects returned promise
    return new Promise(function(resolve) {
      resolve(123);
    });
  });
}

testError().catch(err => console.log("Caught " + err));

这在 async 函数中是隐含的;他们总是return一个承诺:

async function testError() {
  throw new Error("new error"); // rejects implicit promise
  return await new Promise(function(resolve) {
    resolve(123);
  });
}

testError().catch(err => console.log("Caught " + err));