使用First Level try ... catch捕获JavaScript承诺中的错误

时间:2014-07-27 02:59:42

标签: javascript node.js promise bluebird

所以,我希望我的第一级抓捕能够处理错误。反正有没有将我的错误传播到第一次捕获?

参考代码,但尚未运行:

Promise = require('./framework/libraries/bluebird.js');

function promise() {
    var promise = new Promise(function(resolve, reject) {
        throw('Oh no!');
    });

    promise.catch(function(error) {
        throw(error);
    });
}

try {   
    promise();
}
// I WANT THIS CATCH TO CATCH THE ERROR THROWN IN THE PROMISE
catch(error) {
    console.log('Caught!', error);
}

4 个答案:

答案 0 :(得分:31)

您不能使用try-catch语句来处理异步抛出的异常,因为函数在抛出任何异常之前已“返​​回”。您应该使用promise.thenpromise.catch方法,它们代表try-catch语句的异步等价物。

您需要做的是返回承诺,然后将另一个.catch链接到它:

function promise() {
    var promise = new Promise(function(resolve, reject) {
        throw('Oh no!');
    });

    return promise.catch(function(error) {
        throw(error);
    });
}

promise().catch(function(error) {
    console.log('Caught!', error);
});

Promise是可链接的,因此如果一个promise重新出现错误,它将被委托给下一个.catch

顺便说一句,您不需要在throw语句周围使用括号(throw athrow(a)相同)。


如果您在Node.js中运行此代码,并且由于某种原因您不允许编辑promise函数,则可以使用域来执行此操作。请注意,域并不是最容易处理的事情,并且在某些情况下确实存在一些恼人的边缘情况。 除非您真的需要,否则我强烈建议您使用promises。

答案 1 :(得分:20)

使用新的async/await syntax,您可以实现此目标。请注意,在撰写本文时,并非所有浏览器都支持此操作,您可能需要使用babel(或类似内容)来转换代码。

// Because of the "async" keyword here, calling getSomeValue()
// will return a promise.
async function getSomeValue() {
  if (somethingIsNotOk) {
    throw new Error('uh oh');
  } else {
    return 'Yay!';
  }
}

async function() {
  try {
    // "await" will wait for the promise to resolve or reject
    // if it rejects, an error will be thrown, which you can
    // catch with a regular try/catch block
    const someValue = await getSomeValue();
    doSomethingWith(someValue);
  } catch (error) {
    console.error(error);
  }
}

答案 2 :(得分:5)

不!这完全不可能,因为承诺本质上是异步的。抛出异常时,try-catch子句将完成执行(并且仍然不会发明时间旅行)。

相反,从所有函数返回promise,并在它们上挂钩错误处理程序。

答案 3 :(得分:2)

我经常发现需要确保返回Promise,并且几乎经常需要处理本地错误然后可选地重新抛出它。

function doSomeWork() {
  return Promise.try(function() {

    return request.get(url).then(function(response) {
      // ... do some specific work
    });

  }).catch(function(err) {
    console.log("Some specific work failed", err);
    throw err; // IMPORTANT! throw unless you intend to suppress the error
  });
}

这项技术(Promise.try / catch)的好处是你可以启动/确保一个没有解决/拒绝要求的Promise链,这很容易被错过并产生调试噩梦。