【发布时间】:2015-02-05 06:03:22
【问题描述】:
您好,我有一个方法,我使用 bluebird 提供的 Promise 类根据第三方函数的结果来解决或拒绝。我担心的是第三方函数是同步的,因此可能会引发错误。以下是我的代码:
Authenticator.prototype.createJWTResponse = function(user, secret) {
if (user && user.ID) {
var expires = moment().add(7, 'days').valueOf();
//encode is third party and synchronous that can throw error
var token = jwt.encode({
iss: user.ID,
exp: expires
}, secret);
//throw new Error("thrown by a promise method");
return Promise.resolve({
token: token,
expires: expires,
user: {}
});
} else {
return Promise.reject(new Error('Authenticator:createJWTResponse: user object missing or doesnt have ID'));
}
};
一种选择是我不在方法中使用拒绝和响应,而是将其设为正常的回调方法,然后由 Promise.promisify 承诺。但是我的问题是;如果有办法使用resolve和reject并创建一个promise,以防第三方方法抛出异常。 我的另一个问题是;蓝鸟文档中没有说明;如果有人在方法中使用resolve和reject;可以承诺这种方法吗? 我试图承诺上述方法,但由于某种原因它无法返回并且没有抛出错误;这让我怀疑,如果一个人在一个方法中使用了 resolve,reject,那么这样的方法就不能被承诺。
有人可以为我澄清一下吗?提前致谢。
(更新)
如果我将方法包装在 Promise.method 中; bluebird 抛出一个非常明显的错误如下:
可能未处理的错误:否则承诺返回方法中的同步错误
从该方法内部返回 Promise.try 也会引发与 Promise.method 相同的错误。
将方法中的代码包装在 try catch 中并在错误时拒绝也会抛出:
可能未处理的错误:
(解决方案)
按照本杰明的建议;从方法中删除所有解析和拒绝调用并将其包装在 Promise.method 中会产生预期的结果。最终代码如下:
Authenticator.prototype.createJWTResponse = Promise.method(function(user, secret) {
if (user && user.ID) {
var expires = moment().add(7, 'days').valueOf();
var token = jwt.encode({
iss: user.ID,
exp: expires
}, secret);
//Note: This is caught by the catch block on this method
//throw new Error('sync error thrown');
return {
token: token,
expires: expires,
user: {}
}
} else {
throw new Error('Authenticator:createJWTResponse: user object missing or doesnt have id');
}
});
在这种情况下,甚至不需要回调。
【问题讨论】:
-
为什么不把第三方方法放在 try/catch 块中,并在出错时返回一个被拒绝的承诺
-
@johndoe90 这似乎是在不使用 promisify 的情况下让代码正常工作的最合乎逻辑的方式。
标签: javascript node.js promise bluebird