I'm trying to implement a timeout for an asynchronous function using a promise and setTimeout. I want to run an asynchronous operation, and if it doesn't plete by a certain amount of time, throw an error. Currently, this is what I have: (some of it found on 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;
});
But the program doesn't stop when the error is thrown. Would anybody be able to tell me why, and if there is an easier way to do this? I'd be very much appreciative.
EDIT: Now trying to use bluebird for the first time and it is giving someOperationPromised.timeout is not a function. Am I doing this correctly?
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;
});
I'm trying to implement a timeout for an asynchronous function using a promise and setTimeout. I want to run an asynchronous operation, and if it doesn't plete by a certain amount of time, throw an error. Currently, this is what I have: (some of it found on 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;
});
But the program doesn't stop when the error is thrown. Would anybody be able to tell me why, and if there is an easier way to do this? I'd be very much appreciative.
EDIT: Now trying to use bluebird for the first time and it is giving someOperationPromised.timeout is not a function. Am I doing this correctly?
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;
});
Share
Improve this question
edited Aug 3, 2016 at 2:11
Bergi
667k161 gold badges1k silver badges1.5k bronze badges
asked Aug 2, 2016 at 21:39
ChaseChase
712 silver badges6 bronze badges
3
- 1 "the program doesn't stop" - what do you mean by that? Do you expect the 2 second operation to be cancelled? No, you'll have to do that explicitly. – Bergi Commented Aug 3, 2016 at 2:11
-
1
You have to actually call
someOperationPromised()
with the parens after it. – jfriend00 Commented Aug 3, 2016 at 4:25 -
" "the program doesn't stop" - what do you mean by that? " is a very snappy question. Once the [[PromiseStatus]] is set as
rejected
the resolutions ing after that wont have any effect on the promise status. At the meantime yoursomeOperation
function will run however since you are expected to resolve it's result and consume it at the then stage'sonfulfillment
calback, it will result nothing because theonfulfillment
callback will not be called. This is how things get cancelled in promises. – Redu Commented Aug 3, 2016 at 9:57
1 Answer
Reset to default 4Not sure what promise library you're using, if any. May I suggest Bluebird? It's faster than native and has a lot of great features. Among them? Timeout.
From the 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");
});
Edit:
Hey there! I took some time sorting through this, trying to figure out why your edit didn't work. My goal is to prove to you that .timeout()
works. Moreover, I would like to provide you with a workable solution you can use moving forward with Bluebird.
Below I include a function I've named takesFourSeconds
. It returns a promise that will resolve after 4 seconds. I then call takesFourSeconds
twice. The first time I use timeout to force the promise chain to reject if it takes more than 3 seconds. The second time I force it to reject if it takes longer than 5 seconds.
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");
});
Note that this returns:
$ node index.js
promise took longer than 3 seconds
hi
As expected.
Small side note:
When creating a function that returns a promise, you don't have to create a new promise for every function you call in a chain of promises. Only the first function.
For example, if I wanted to call another function after takesFourSeconds()
I could write it like this:
function myFunc(result){
return result === 'hi' ? resolve('hey there') : reject('hi there');
}
then:
takesFourSeconds()
.then(myFunc) // myFunc will take in the resolved value of takesFourSeconds implicitly
.then(result => console.log(result)
.catch(error => console.log(error);
This should output:
"hey there"
There you have it! Timeouts in Bluebird.js. :)
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745047237a4608173.html
评论列表(0条)