在try/catch块中包装promise是正确的方法吗
Is wrapping a promise in a try/catch block the proper method?
我有一个函数可以调用promise。关于成功或失败,我想返回一些超出承诺返回的数据。
我认为这可能奏效:
function foo() {
const extra = 'bar'
return thepromise().then((res) => {
return {
result: res,
data: extra
}
}, (err) => {
// this will not happen if an error is thrown in the called promise
return {
result: res,
data: extra
}
})
}
foo().then((res) => { }, (err) => { // error result ends up here })
然而,这并不奏效。如果在thepromise
中抛出错误,它将不调用catch块,而是调用foo()
的catch块。
处理这个问题的正确方法是什么?我成功地尝试了一次拦截,但我不确定这是最好的方法:
function foo() {
const extra = 'bar'
return new Promise((resolve, reject) => {
try {
return thepromise(p)
} catch (e) {
reject(e)
}
})
.then(function(res) {
return {
result: res,
data: extra,
status: 'success'
}
}, function(err) {
return {
result: err,
data: extra
status: 'error'
}
})
}
任何旨在返回promise的函数都不应该抛出任何类型的异常或错误。
如果是这样的话,它应该被认为是有缺陷的。
要修复有缺陷的方法,不要抛出异常,而是拒绝返回的promise。
有时您无法修复潜在的bug,例如当您使用他人的API时。如果是这种情况,首先也是最重要的一件事就是向原始作者报告错误,以便修复潜在的问题。
报告问题后,您可以用一个简单的实用程序来包装有缺陷的方法来修复问题:
function fixBrokenPromise(promise/*, args...*/) {
var args = Array.prototype.slice.call(arguments, 1),
ret;
try {
ret = promise.apply(null, args);
} catch (ex) {
ret = Promise.reject(ex);
}
return ret;
}
这可以称为:
fixBrokenPromise(thepromise/*, args you want to pass to thepromise */)
.then(...resolve...,
...reject...);
如果您愿意接受Promises的扩展,bluebird
有一个可以满足您需要的尝试方法:
import Promise from 'bluebird';
// ...
return Promise
.try(thepromise)
.then(res => ({
result: res,
data: extra
})
.catch(err => ({
result: res,
data: extra
});
该错误被认为是在.catch()
处处理的,它将向链接的.then()
返回已解析的promise。您可以将错误throw
发送到下一个.catch()
function foo() {
const extra = 'bar'
return thepromise().then((res) => {
return {
result: res,
data: extra
}
}, (err) => {
throw new Error(JSON.stringify({
result: err || "no rejection reason provided",
data: extra
}))
})
}
var thepromise = () => Promise.reject();
foo().then(data => console.log("fulfilled", data))
.catch(err => console.log("catch", JSON.parse(err.message)))
相关文章:
- 将一个方法转换为promise:Nodejs
- 将其中一个异步方法重写为使用promise的方法
- Ember.js:将Em.$.getJSON转换为promise并将响应绑定到控制器上下文的正确方法
- 多次调用方法后返回相同promise的模式
- 将数据从promise then方法传递到对象方法
- jQuery Deferred and promise-错误:对象没有't支持属性或方法'然后'
- 与 promise 一起使用时,异步瀑布不执行下一个回调方法
- 传递promise回调方法的更好方法
- Angular promise回调不是在构造函数方法内部触发,而是在对象文本方法中触发
- 迭代Promise迭代器的非递归方法
- 如何重写这段代码,使执行不必从Javascript Promise.then()方法开始
- 如何使EXPECT条件等待promise被解析(代码封装在方法中)
- Promise.all()方法没有't解析为一个值
- 如何将嵌套_.each转换为同步方法?首选使用 Promise 或 Async.waterfall
- 为什么返回的 Promise 在登录到控制台时没有方法
- 为什么来自 Promise '.then' 方法的回调是反模式
- 在循环中使用 q promise 的最佳方法是什么?等待链完成,然后再迭代到下一个
- 返回带有mocha的promise的测试方法调用
- 在Promise回调中调用Meteor方法[无错误暂停]
- 是否有一种纯粹基于Promise的方法来映射/连接集合