如果sendToSocket成功,为什么setTimeout
def.reject
代码不能运行?
this.send = function(type, body) {
var def = Promise.defer();
try{
sendToSocket({...});
setTimeout(function() { // if the send sendToSocket Succeeds how does nodejs/javascript know not to run the timeout code after 10 seconds?
def.reject(new Error("timeout"));
}, 10000);
}catch(err){
logger.error('error');
def.reject(err);
}
return def.promise;
};
答案 0 :(得分:2)
正如评论所说,承诺的状态只能改变一次,从待决到履行或拒绝。一旦承诺得到履行,拒绝将被忽略。
此外,它被认为是更好的形式不使用Promise.defer()
而是使用new Promise
构造函数:
return new Promise(function(resolve, reject) {
sendToSocket({...}); // call resolve() here
setTimeout(function() { reject(new Error("timeout")); }, 10000)
});
你注意到这里没有try/catch
,因为在Promise构造函数中,任何抛出的异常都会自动转换为拒绝。
我会做的另一个事情是将方法与超时分开,如下所示:
function withTimeout(delay, fn) {
return function() {
return Promise.race([ // race between...
// Promise that rejects after "delay" ms
new Promise(function(resolve, reject) {
setTimeout(function() { reject(new Error("timeout")); }, delay);
}), // and...
// Promise that actually does the action
// The call to `Promise.resolve()` is to ensure we get a Promise
// even if the function doesn't return one.
Promise.resolve(fn.apply(null, arguments))
]);
};
}
this.send = function() {
return new Promise(function(resolve, reject) {
sendToSocket({...}); // call resolve here, or reject on error.
// thrown errors will be converted anyway
});
};
this.sendWithTimeout = withTimeout(10000, this.send.bind(this));
调用withTimeout
将返回新函数,返回带有超时选项的Promise。
Promise.race()
返回一个Promise,它在传递的Promises数组中的第一个Promise解析或拒绝时解析(或拒绝)。我们在this.send()
返回的实际承诺和在超时时拒绝的承诺之间竞赛。
这意味着您的this.send()
功能仅处理实际发送。超时是您通过抽象添加的细节。