如果 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;
};
最佳答案
正如评论所说,Promise 的状态只能更改一次,从待处理更改为已完成或已拒绝。一旦履行了 promise ,拒绝将被忽略。
此外,不使用 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,当传递的 Promise 数组中的第一个 Promise 解析或拒绝时,该 Promise 会解析(或拒绝)。我们正在从 this.send()
返回的实际 Promise 和超时时拒绝的 Promise 之间进行竞争。
这意味着您的 this.send()
函数仅处理实际发送。超时是您通过抽象添加的详细信息。
关于javascript - 如果 sendToSocket 成功,为什么 setTimeout def.reject 代码不会运行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39613982/