2

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.

4

2 回答 2

6

我认为你对自己的关注程度太低了。一旦你运行了test1,就没有办法停止db_rw_pool.query执行,并且它的回调被调用(除非你在这个db_rw_pool.query方法中采取了特殊的预防措施)。SQL 查询的结果将返回。问题是代码是否会在某个时候吞下这些结果。这种情况下的吞咽发生在 Qtimeout方法的代码中。只需将您不想执行的任何代码放在done.

你写

问题是我需要在一定时间后停止执行该函数,所以我使用了 Q 模块的函数“超时”。

timeout 方法不会停止此函数的执行。相反,它会返回一个新的 Promise,如果它绑定的 Promise(你已经做出的承诺Q.nfcall)没有在设定的时间段内(在本例中为 1000 毫秒)内实现,则该 Promise 会被指示失败。

如果您想以某种方式阻止回调执行,则可以将其包装在一个检查时间的函数中。就像是:

function stopExecutingAfter(timeout, fn) {
  var stopifAfter = Date.now() + timeout
  return function() {
    if(Date.now() > stopIfAfter) return
    fn.apply(null, arguments)
  }
}

Q 主要关注承诺,所以很明显它不会为你做这件事。使用这种技术,您可以创建一个nfcallWithTimeout返回 Promise 的函数,同时保护传递的函数(通过将其包装在类似上面的东西中)。然后您不必配置两次超时行为。

于 2013-05-10T09:55:52.393 回答
-1

考虑使用另一种语言,因为在 Javascript 中无法做到这一点。

于 2021-02-25T01:33:29.917 回答