javascript - 如果 sendToSocket 成功,为什么 setTimeout def.reject 代码不会运行?

标签 javascript node.js

如果 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/

相关文章:

javascript - 如果存在则追加到列表或在 dynamoDB 中添加列表

node.js - 使用 Node.js 将流分块为数据 block

node.js - 如何在nodeJS上未经身份验证跟踪用户

javascript - 匹配 JavaScript 文件,但不包括 mocha 测试文件

javascript - 如何在 Express 中设置 IP 白名单?

javascript - 使用 JS/CSS 缩小工具作为 python distutils 命令?

javascript - 使用后如何从 GPU 清理和卸载 WebGL Canvas 上下文?

javascript - AJAX 表单提交后永无止境的 "Connecting"消息

javascript - 复杂的 JQuery 选择器 - 如何选择任意一个 'generation' ?

javascript - Google Places API 显示学校和商店