使用承诺实现超时 - 抛出错误
Using a promise to implement a timeout - throw an error
我正在尝试使用 promise 和 setTimeout 为异步函数实现超时。我想 运行 一个异步操作,如果它在一定时间内没有完成,就抛出一个错误。目前,这就是我所拥有的:(其中一些是在 Whosebug 上找到的)
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 吗?它比本机更快,并且具有许多强大的功能。他们之中?超时。
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
的函数。它 returns 将在 4 秒后解决的承诺。然后我调用 takesFourSeconds
两次。我第一次使用超时强制承诺链在超过 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");
});
注意这个 returns:
$ node index.js
promise took longer than 3 seconds
hi
符合预期。
小旁注:
创建一个 returns 承诺的函数时,您不必为在承诺链中调用的每个函数都创建一个新承诺。只有第一个功能。
例如,如果我想在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 超时。 :)
我正在尝试使用 promise 和 setTimeout 为异步函数实现超时。我想 运行 一个异步操作,如果它在一定时间内没有完成,就抛出一个错误。目前,这就是我所拥有的:(其中一些是在 Whosebug 上找到的)
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 吗?它比本机更快,并且具有许多强大的功能。他们之中?超时。
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
的函数。它 returns 将在 4 秒后解决的承诺。然后我调用 takesFourSeconds
两次。我第一次使用超时强制承诺链在超过 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");
});
注意这个 returns:
$ node index.js
promise took longer than 3 seconds
hi
符合预期。
小旁注:
创建一个 returns 承诺的函数时,您不必为在承诺链中调用的每个函数都创建一个新承诺。只有第一个功能。
例如,如果我想在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 超时。 :)