嗨,我有一个方法,我使用 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 承诺。然而,我的问题是;如果有办法使用解析和拒绝并创建承诺,以防第三方方法引发异常。我的另一个问题是;蓝鸟文档中没有说明;如果一个人在一种方法中使用解决和拒绝;这样的方法可以有希望吗?我试图承诺上述方法,但由于某种原因它无法返回并且没有抛出错误;这让我怀疑,如果一个人在一种方法中使用解析,拒绝,那么这种方法就不能被承诺。
有人可以为我澄清这一点吗?提前谢谢。
(更新(
如果我将该方法包装在 Promise.method 中;蓝鸟会抛出一个非常明显的错误,如下所示:
可能未处理的错误:否则承诺返回方法中的同步错误
从此方法内部返回 Promise.try 也会引发与 Promise.method 相同的错误。
将方法中的代码包装在 try catch 中并在错误时拒绝也会引发:
可能未处理的错误:
(解决方案(
正如 Benjamin 所建议的;从方法中取出所有解析和拒绝调用,并将其包装在 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');
}
});
在这种情况下,甚至不需要回调。
首先,.promisify 已经将抛出转换为拒绝。
至于正常的承诺 - promise 构造函数是安全的,你可以使用Promise.method
它是安全的。
将同步抛出转换为拒绝的原因是为了创建一致的 API,因此您不必一直使用 .catch 和 catch。