【问题标题】:asynchronous function in promise throws error and doesn't reject [duplicate]承诺中的异步函数抛出错误并且不拒绝[重复]
【发布时间】:2019-07-03 19:37:09
【问题描述】:

如果有一个带有异步函数的 Promise,并且如果在异步函数中发生错误,则 Promise 不会捕获但会引发错误并使应用程序崩溃,我不明白。

显然我想处理这个错误,你知道为什么承诺会这样吗?有什么办法可以解决它?

谢谢

// this promise will have an error since param is not defined,
// and the promise won't be caught
function randomPromise(param) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            param[0] = 11;
        }, 2000);
    });
}

randomPromise()
.then(() => {
    console.log('nothing');
})
.catch((e) => {
    console.log('with set timeout or any async function in the promise, the error caused by \'param[0] = 11;\' wont bring the control here into the catch block just throws an error and crashes the application');
    console.log(e);
});

// this promise will have an error since param is not defined
// but the promise will be caught
function randomPromiseGoesToCatchBlock(param) {
    return new Promise((resolve, reject) => {
        param[0] = 11;
    });
}

randomPromiseGoesToCatchBlock()
.then(() => {
    console.log('nothing');
})
.catch((e) => {
    console.log('without the setTimeout function or any async function the error caused by \'param[0] = 11;\' brings the control here into the catch block');
    console.log(e);
});

【问题讨论】:

    标签: javascript asynchronous error-handling promise catch-block


    【解决方案1】:

    Promise 构造函数中抛出的错误异步需要显式try/catched 以便可以调用reject,以便Promise 控制流量可以转移到 Promise 的catch。例如:

    // this promise will have an error since param is not defined, and the promise wont be catched
    function randomPromise(param) {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          try {
            param[0] = 11;
          } catch(e) {
            reject(e);
          }
        }, 2000);
      });
    }
    
    randomPromise()
      .catch((e) => {
        console.log(e.message);
      });

    否则,resolvereject 都不会被调用,并且错误是异步的,因此创建 Promise 的线程已经结束,因此解释器不知道抛出的错误应该拒绝该 Promise没有你明确告诉它。

    相比之下,Promise 构造函数中同步抛出的错误将自动导致构造的 Promise 立即拒绝。

    【讨论】:

    • so the thread the Promise was created on has already ended - 我认为 Javascript 没有多线程。你能解释一下当异步方法中抛出异常时,Javascript 内部会发生什么吗?
    • 是的,在大多数情况下,Javascript 是单线程的。也许说错误发生在事件循环的不同迭代中会更有意义。如果在异步执行期间抛出一个错误,并且同步调用堆栈从.then 开始,它将导致该.then 的Promise 被拒绝(如果处理不当,则会导致unhandledRejection)。否则,如果同步调用堆栈中没有.then(例如这里抛出错误时同步调用堆栈的顶部是setTimeout回调),则会导致标准错误。
    • 酷,让我们看看我是否理解这一点。当异步函数运行时(例如 setTimeout),事件循环不知道它在 Promise 中运行。所以异步调用中的错误会导致程序崩溃。但是,如果我们通过调用 Promise 的 reject 来专门处理错误,它会将控制权交还给 Promise,从而避免程序崩溃。
    • 由于它不在主线程上,它可能不会“崩溃”程序,它只会记录有错误。如果你调用reject,或者在.then 中同步抛出,错误会被传递给 Promise 来处理。如果 Promise 未处理错误,您将收到未处理的拒绝。未处理拒绝的错误消息是不同的,但发生了相同的一般类型的事情 - 抛出了一个未被捕获的错误。
    猜你喜欢
    • 1970-01-01
    • 2015-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-22
    • 1970-01-01
    • 2017-08-22
    相关资源
    最近更新 更多