【问题标题】:How to handle an unexpected error from a function after result is return from function in JavaScript?从 JavaScript 中的函数返回结果后如何处理函数的意外错误?
【发布时间】:2019-01-26 00:22:20
【问题描述】:

在处理 JavaScript 中的异步函数时。我发现了这个问题。

函数需要执行一些异步任务,但是该任务对函数结果没有影响。所以函数返回它的结果,一段时间后,异步函数抛出异常,但是由于控制已经返回,所以异常没有处理。

注意:不要更改notify我故意抛出这样的错误,只需要处理这个异常

代码如下:

function notify() {   //To send notification
    setTimeout( function() {   //Just to simulate an asynchronous function
        throw "Exception occurred";   //An exception from async function
    },2000);

    return "Notified";
}

try {
    let result = notify();
    console.log(result);    //Notified
}
catch (error) {   //Never comes to catch block.
    console.log(error);
}

如何捕捉这个异常。 尝试使用 Promise,但它不能通过 Promise 解决,因为即使使用 Promise,由于调用函数已收到响应,流或函数也会从内存中删除。

使用承诺的代码

function notify() {   //To send notification

    return new Promise ( (resolve, reject) => {
        setTimeout( function() {   //Just to simulate an asynchronous function
            throw "Exception occurred";   //An exception from async function
        },2000);

        resolve("Notified");
    });
}

notify()
.then( result => {
    console.log(result);    //Notified
})
.catch( error => {   //Never comes to catch block
    console.log(error);
});

如何在 JavaScript 编程中捕获异常?

【问题讨论】:

  • 我将首先重新评估您最初的说法,即“任务对功能结果没有影响”。如果在尝试发送通知时发生异常,那么知道是否成功的结果显然取决于该异步任务。
  • 我认为this post 应该回答你的问题
  • notify 不应立即resolve()。它应该调用reject() 而不是throw 处理异常。

标签: javascript node.js ecmascript-6 es6-promise ecmascript-5


【解决方案1】:
    var notify = function () {
        anOddTask();
        return "Notified";
    }


    async function anOddTask() {
        try {
            await setTimeout( function() {  
            },2000);
            throw new Error("Exception occurred");
        }
        catch (err) {   
            console.log(err);
        }
    }

    try {
        let result = notify();
        console.log(result);    //Notified
    }
    catch (error) {   //Never comes to catch block.
        console.log(error);
    }

这将立即返回“通知”并在稍后处理拒绝。如果您希望“通知”作为已解决的承诺返回,而不仅仅是将 notify() 设为异步函数。

    var notify = async function () {
        anOddTask();
        return "Notified";
    }

【讨论】:

    【解决方案2】:

    我会将 setTimeout 包装在一个承诺中:

      const delay = ms => new Promise(res => setTimeout(res, ms));
    

    这允许您将notify 写为:

      async function notify() {
        await delay(2000);
        throw new Error();
      }
    
      notify().then(/*...*/).catch(/*...*/);
    

    这里的诀窍是 throw 在异步函数内部,而不是在回调内部。

    【讨论】:

    • 是的,这修复了 throws 在 setTimeout 回调中的 OPs 代码,但不持有 "所以函数返回它的结果,并且在一段时间后出现异常被抛出”了
    • @bergi notify().catch(...); getResult().then(...) ...但这很难从 OPs 代码中分辨出来。
    • 我的问题不同。您要求我等待该异步函数返回或完成其执行。我不想等待它的执行。但是,如果该异步函数抛出错误,我的应用程序将被终止。
    • @navin 然后使用 Promise.race
    猜你喜欢
    • 2011-05-19
    • 1970-01-01
    • 1970-01-01
    • 2012-09-10
    • 2011-12-02
    • 1970-01-01
    • 2013-06-03
    • 2019-10-17
    • 2011-11-07
    相关资源
    最近更新 更多