【问题标题】:How do I handle errors with promises?如何处理 promise 的错误?
【发布时间】: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 进行这种错误处理?

【问题讨论】:

    标签: javascript node.js error-handling promise bluebird


    【解决方案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

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

    【讨论】:

      【解决方案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
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-02-17
        • 2016-09-29
        • 2021-02-19
        • 2017-08-21
        • 2019-01-05
        • 2016-04-20
        • 2016-06-08
        相关资源
        最近更新 更多