Reputation: 538
I've been using the Q module to implement promises on a project I'm working on. I'm using the static method Q.fncall() to create a promise out of a node.js style function (based on callbacks returning err,result).
The problem is that I need to stop the execution of said function after a certain amount of time, so I used the function "timeout" of the Q module. So, after x amount of time, the "error" callback on the done function executes and let's me handle the timeout but the function itself keeps getting executed until it reaches its final callback even if the handler is not listening anymore.
The question is: Is there any way to stop the execution of a function after the timeout is executed? I know I can just set a variable on the timeout handler and keep checking in the function if the timeout is over, but I'm hoping for a cleaner way of achieving this.
The code is as follows:
Q.nfcall(test1, id)
.timeout(1000)
.done(
function (value) {
console.log("SUCCESS: " + value);
},
function (reason) {
console.log("ERROR " + reason);
},
function (progress) {
console.log("PROGRESS " + progress);
}
);
And the test1 function:
function test1(id,callback){
db_rw_pool.query("SELECT * FROM table WHERE id=?",[id], function(err,result) {
if(err){
callback(err,null);
}
else {
setTimeout(function(){
console.log("I DON'T WANT YOU TO BRE PRINTED")
callback(null,result);
},2000);
}
return;
});
}
In my ideal situation, the code inside setTimeout(...,2000) should never be executed. Is this possible?
Thanks in advance.
Upvotes: 2
Views: 2645
Reputation: 1
Consider using another language because there is no way to do this in Javascript.
Upvotes: -1
Reputation: 11438
I think you're concerning yourself over a too low level. Once you've ran test1
, there's no way to stop db_rw_pool.query
from executing, and its callback from being called (unless you'd take special precautions in this db_rw_pool.query
method). The results for the SQL query WILL come back. The question is whether the code will swallow these results at some point, or not. The swallowing in this case happens in the code for Q's timeout
method. Just place any code you don't want to be executed in the onFulfilled handler of done
.
You write
The problem is that I need to stop the execution of said function after a certain amount of time, so I used the function "timeout" of the Q module.
The timeout method won't stop this function from executing. Rather, it returns a new promise that is instructed to fail if the promise it's bound to (the one which you've made with Q.nfcall
) is not fulfilled within the set period (1000 ms in this case).
If you somehow want to stop a callback from executing, you could wrap it inside a function that checks for the time. Something like:
function stopExecutingAfter(timeout, fn) {
var stopifAfter = Date.now() + timeout
return function() {
if(Date.now() > stopIfAfter) return
fn.apply(null, arguments)
}
}
Q mainly concerns itself with promises, so it's obvious that it won't do this for you.
Using this technique, you could make a nfcallWithTimeout
function that returns a promise while protecting the passed function (by wrapping it in something like the above) as well. Then you don't have to configure the timeout behavior twice.
Upvotes: 6