javascript - 使用 promise 实现超时 - 抛出错误

标签 javascript node.js promise cancellation

我正在尝试使用 promise 和 setTimeout 为异步函数实现超时。我想运行一个异步操作,如果它在一定时间内没有完成,则抛出一个错误。目前,这就是我所拥有的:(其中一些是在 stackoverflow 上找到的)

function someOperation(cb) {
  setTimeout(function() {
    cb(null, 'Done');
  }, 2000);
}


var p = new Promise(function(resolve, reject) {
  setTimeout(function() {
    reject(new Error('Operation timed out'));
  }, 100);

  someOperation(function(err, res) {
    if (err) reject(err);
    else resolve(res);
  });

});

p.then(function(res) {
  console.log(res);
}, function(err) {
  console.log("Throwing error...")
  throw err;
});

但是当错误被抛出时程序并没有停止。谁能告诉我为什么,如果有更简单的方法来做到这一点?我将不胜感激。

编辑:现在第一次尝试使用 bluebird,它给出了 someOperationPromised.timeout 不是函数。我这样做正确吗?

var Promise = require("bluebird");

function someOperation(cb) {
  setTimeout(function() {
    cb('', 'Done');
  }, 2000);
}

var someOperationPromised = Promise.promisify(someOperation);

someOperationPromised.timeout(1).then(function (){
  console.log("Finished!");
}).catch(Promise.TimeoutError, function (err) {
  throw err;
});

最佳答案

不确定您使用的是什么 promise 库(如果有的话)。我可以建议 Bluebird ?它比 native 更快,并且具有许多强大的功能。其中?超时。

来自documentation :

var Promise = require("bluebird");
var fs = Promise.promisifyAll(require('fs'));
fs.readFileAsync("huge-file.txt").timeout(100).then(function(fileContents) {

}).catch(Promise.TimeoutError, function(e) {
    console.log("could not read file within 100ms");
});

编辑:

你好!我花了一些时间整理这个,试图弄清楚为什么你的编辑不起作用。我的目标是向您证明 .timeout() 有效。此外,我想为您提供一个可行的解决方案,您可以使用它继续使用 Bluebird。

下面我包含了一个我命名为 takesFourSeconds 的函数。它返回一个将在 4 秒后解决的 promise 。然后我调用 takesFourSeconds 两次。我第一次使用超时强制 promise 链在超过 3 秒时拒绝。第二次,如果超过 5 秒,我强制它拒绝。

var Promise = require("bluebird");

function takesFourSeconds (){
    return new Promise((resolve, reject) => {
        setTimeout(function(){
            return resolve('hi');
        }, 4000);
    });
}

takesFourSeconds().timeout(3000).then(function(res) {
    console.log(res);
}).catch(Promise.TimeoutError, function(e) {
    console.log("promise took longer than 3 seconds");
});

takesFourSeconds().timeout(5000).then(function(res) {
    console.log(res);
}).catch(Promise.TimeoutError, function(e) {
    console.log("promise took longer than 5 seconds");
});

请注意,这会返回:

$ node index.js
promise took longer than 3 seconds
hi

正如预期的那样。

小旁注:

当创建一个返回 promise 的函数时,您不必为在 promise 链中调用的每个函数都创建一个新 promise 。只有第一个功能。

例如,如果我想在 takesFourSeconds() 之后调用另一个函数,我可以这样写:

function myFunc(result){
  return result === 'hi' ? resolve('hey there') : reject('hi there');
}

然后:

takesFourSeconds()
  .then(myFunc) // myFunc will take in the resolved value of takesFourSeconds implicitly
  .then(result => console.log(result)
  .catch(error => console.log(error);

这应该输出:

"hey there"

给你! Bluebird.js 中的超时。 :)

关于javascript - 使用 promise 实现超时 - 抛出错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38730914/

相关文章:

node.js - 一旦客户端断开连接并再次连接服务器位于 Socket.io 和 node.js 上,Socket Id 是否会重新发出?

javascript - 禁用默认的 Polymer CSS

javascript - Angular JS 当前范围是什么?

node.js - 为什么我得到 for 循环的 array[i] value is undefined

javascript - 如何返回许多 Promise 并在做其他事情之前等待它们全部

javascript - JavaScript (ES6) 中的原生 promise 是否具有默认的 onFulfilled 处理程序?

javascript - Q.js promise 与 Node 。 `socket` 上缺少错误处理程序。类型错误 : Cannot call method 'then' of undefined

javascript - 使用 --- innerHTML = "...<a href=' http ://. 在 javascript 函数中创建链接。 .'>HttpLink</a>..."

javascript - D3 - 在 svg 中将滚动应用到图例容器时出现问题

javascript - Discord 聊天机器人更改 channel 帖子权限