如何处理 promise 的错误?

Posted

技术标签:

【中文标题】如何处理 promise 的错误?【英文标题】:How do I handle errors with promises? 【发布时间】:2014-03-15 00:47:39 【问题描述】:

作为节点程序员。我习惯于使用“nodebacks”来处理我的代码中的错误:

myFn(param, function(err, data) 
    if (err)
        //error handling logic
     
     else 
        // business logic
    
);

在编写该函数时,我可以执行以下操作:

var myFn = function(param, callback)
    var calc = doSomeCalculation(param);
    if(calc === null)  // or some other way to detect error
        callback(new Error("error with calculation"), null);
    
    ...
    someAsyncOp(calcN,function(err, finalResult)
        if(err) return callback(err, null);
        callback(null, finalResult); // the error is null to signal no error
    );

;

我将如何使用 Promise 进行这种错误处理?

【问题讨论】:

【参考方案1】:

经验法则

当您对如何使用 Promise 做某事有疑问时,请考虑同步版本。

try
   var result = myFn(param);
   // business logic with result
 catch(e) 
    //error handling logic

至少在我看来,这比第一个参数有时是 null 的回调要干净得多。

promises 方式几乎总是与问题的同步版本非常相似:

myFn(param).then(function(result)
    // business logic with result
).catch(function(e)
    //error handling logic
);

使用回调时 myFn 的样子:

var myFn = function(param)
    return new Promise(function(resolve, reject)
        var calc = doSomeCalculation(param);
        if(calc === null)  // or some other way to detect error
            reject(new Error("error with calculation"), null);
        
        someAsyncOp(calcN,function(err, finalResult)
            if(err) reject(err);
            resolve(finalResult);
        )
    );
;

使用回调/nodebacks

这只是你在使用回调时应该做的事情,在使用 Promise 时它要简单得多,你可以这样做:

var myFn = function(param)
    var calc = doSomeCalculation(param);
    ...
    return someAsyncOp(calcN); // returning a promise.

此外,在 Promise 链中工作时,您会获得安全性:

myFn(param).then(function(calcN)
   // here, you throw to raise an error and return to resolve
   // new Promise should be used only when starting a chain.
).catch(function(err)
    // handle error
).then(function()
   // ready to go again, we're out of the catch
);

注意,BluebirdRSVPQ 等一些库提供语法糖和方法的自动承诺,因此您很少需要自己使用 new Promise

另外,请考虑阅读 this 和 that 以了解有关承诺错误处理的更多信息。

【讨论】:

【参考方案2】:

如果您使用的是 async/await 语法,则可以只使用常规的 try-catch 语法进行错误处理。

// your promise function
const myFn = function(param)
  return new Promise(function(resolve, reject)
      if (someLogic()) 
          resolve(someValue);
       else 
          reject('failure reason');
      
  );


// Define the parent function as an async function
async function outerFn(param) 
    try 
        // Wait for the promise to complete using await
        const result = await myFn(param)
        // business logic with result
     catch (e) 
        //error handling logic
    

【讨论】:

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

Q-promises 和错误处理

Promise

promise解决回调地狱

深入解决异步编程Promise对象的学习

deferred对象和promise对象

jQuery的deferred对象和promise对象