如果socket收到了一些请求,则在时间之前执行setTimeout函数

时间:2017-07-28 11:03:12

标签: node.js socket.io

我有一个用例,我在20秒后执行setTimeout函数,但是如果前端的套接字连接在20秒之前返回了某些内容,我希望执行该函数。在这种情况下,我不希望它在20秒后运行。我怎样才能做到这一点。

2 个答案:

答案 0 :(得分:1)

这里最简单的方案是将代码放在与setTimeout()一起使用的函数中,如果定时器仍在运行,则取消定时器并直接调用函数:

function doSomeTask() {
    // code here for your task
}

// schedule task to run in 20 seconds
// remember timer handle so we know it's running
let timer = setTimeout(() => {
    timer = null;
    doSomeTask();
}, 20*1000);

// elsewhere in your code where you want to call your function
// earlier than the timer (if it hasn't already been called)
if (timer) {
    clearTimeout(timer);
    timer = null;
    doSomeTask();
}

Promise可以在这里提供一些好处,因为他们已经确保给定的承诺只能被解决或拒绝一次,并且可以利用这里。为了优雅地使用它们,我可能会创建一个使其非常简单的状态对象。

function delayExecute(fn, t) {
    let obj = {state: "timer"};
    let p = new Promise((resolve, reject) => {
        obj.runNow = resolve;
        obj.cancel = reject;
        setTimeout(resolve, t);
    }).catch(err => {
        obj.state = "err";
        throw err;
    }).then(() => {
        fn();
        obj.state = "done";
    });
    return obj;
}

function doSomeTask() {
    // code here for your task
}

let task = delayExecute(doSomeTask, 20*1000);

// then some time later, to run it sooner (if it hasn't already run)
// calling the .runNow() method after the function has already run will do nothing
task.runNow();

同样的界面也可以在没有承诺的情况下构建。我只是想我会展示如何为此目的利用承诺的单向状态转换。

答案 1 :(得分:0)

你没有多少选择。由于您没有包含有关如何管理并发性的任何代码或信息,因此我将向您展示使用承诺似乎合理的一种方式。

let resolve;
let promise = new Promise(res => resolve = res);

// function to call after max 2s or after response
let fn = () => {
  console.log(process.uptime(), 'Function called');
};

// the timeout:
setTimeout(resolve, 1000);

// the fake response handler:
setTimeout(() => {
  console.log(process.uptime(), 'Request returned');
  resolve();
}, 2000 * Math.random());

promise.then(fn);

then处理程序只运行一次。多次执行该程序,如果在1秒超时触发之前调用伪响应处理程序,则会在调用伪响应处理程序之后立即调用该函数,如果超时是第一个,则立即调用该函数。