如何使用 async/await 处理错误?

Posted

技术标签:

【中文标题】如何使用 async/await 处理错误?【英文标题】:How to handle errors using async/await? 【发布时间】:2018-09-03 10:09:54 【问题描述】:

¿在 nodeJS 中使用 async/await 实现 promise 错误处理程序 .catch((err)=>) 的最佳实践是什么?

代码运行在 nodeJS V8.10.0

这是我实施后者的失败尝试。

考虑以下代码:

使用.catch((err)=>)

    //Function that rejects a promise with a probability of 50%
    function randomReject(resolve,reject)
        setTimeout(()=>
          if(Math.random() > 0.5)
            resolve('Bigger than 1/2');
          else
            reject('Smaller than 1/2');
        ,500)
     

//Test promises
//THESE PROMISES ARE DECLARED INCORRECTLY
var promise1 = new Promise((resolve,reject)=> //HERE IS THE PROBLEM
    randomReject(resolve,reject);
)
var promise2 = new Promise((resolve,reject)=> //HERE IS THE PROBLEM
    randomReject(resolve,reject);
)
//EXPLANATION: Without a wrapper function around the promises, these will 
//run in place as soon as they are declared. And since there is no promise 
//rejection handler declared in the latter code these will cause an
//"UnhandledPromiseRejectionWarning" in NodeJS.

//Async function declaration
async function asyncFnc2()
          var res1 = await promise1;
          var res2 = await promise2;
          return res1 + ' ' +res2; 


//Async function call
asyncFnc2().then((val)=>
    console.log(val);
).catch((err)=>
    console.log(err);
)

控制台输出:

控制台输出指示未处理的承诺拒绝。

非常欢迎任何指向正确方向的指针,以及代码中反模式或不良做法的更正。

提前感谢您的时间和兴趣。

分辨率

function randomReject(resolve,reject)
    setTimeout(()=>
        if(Math.random() > 0.5)
            resolve('Bigger than 1/2');
        else
            reject('Smaller than 1/2');
    ,500)


//Test promises
//These promises are wrapped around functions so they are not run in place
function promise1()
        return new Promise((resolve,reject)=>
             randomReject(resolve,reject);
        )

function promise2() 
        return new Promise((resolve,reject)=>
             randomReject(resolve,reject);
        )
;
//These promises are wrapped around functions so they are not run in place

//No need for the "try catch", just let the async function do the dirty 
//work. 

async function asyncFnc2()
          var res1 = await promise1();
          var res2 = await promise2();
          return res1 + ' ' +res2;


//Any exception will be automatically catch by the ".catch((err)=>)"
asyncFnc2().then((val)=>
    console.log(val);
).catch((error)=>
    console.log(error);
)

【问题讨论】:

How to reject in async/await syntax?的可能重复 我认为你对 Promise 的工作原理有点困惑,..var promise1 = new Promise((resolve,reject)=>,这是一个 Promise,它会立即执行。然后你有 async function asyncFnc2() 等待 promise1promise2,已经开始了,promise3 甚至从未等待。通常当你创建一个新的 Promise 时,你会从另一个函数中调用它。例如..function test() return new Promise(resolve, reject) 等。 【参考方案1】:

查看您的代码,不确定您要做什么。 如果是创建两个promise,然后随机reject或者resolve。

以下是您修改后的代码->

function randomReject()
   return new Promise((resolve, reject) => 
       setTimeout(()=>
        if(Math.random() > 0.5)
            resolve('Bigger than 1/2');
        else
            reject('Smaller than 1/2');
    ,500)
   );


async function asyncFnc2()
    var res1 = await randomReject();
    var res2 = await randomReject();
    return res1 + ' ' +res2;

asyncFnc2().then((val)=>
    console.log(val);
).catch((error)=>
    console.log(error);
)

【讨论】:

谢谢基思!你是绝对正确的。你说:我想你对 Promise 的工作原理有点困惑,.. var promise1 = new Promise((resolve,reject)=>,这是一个 Promise,它会立即执行。然后你有 async 函数asyncFnc2() 在 promise1 和 promise2 上等待,已经开始,并且 promise3 甚至从未等待。通常当你创建一个新的 Promise 时,你会从另一个函数调用它。例如.. function test() return new承诺(解决,拒绝)【参考方案2】:

在第二个示例中,您应该抛出异常而不是试图拒绝承诺。

async function asyncFnc2()
    try
          var res1 = await promise1;
          var res2 = await promise2;
          return res1 + ' ' +res2;
    catch(e)
        throw new Error(e);
    

【讨论】:

以上是关于如何使用 async/await 处理错误?的主要内容,如果未能解决你的问题,请参考以下文章

如何优雅处理 async await 错误——解读小而美的 await-to-js 库

如何使用 async/await 处理同步方法/任务

在 Angular 中,如何在使用 async/await 时处理 Promise 拒绝

如何优雅地处理Async/Await的异常?

Async/await mvc express 使用 .catch() 处理错误的问题

在 Node.js 中使用 async/await 正确处理错误