Node中的setTimeOut()和setInterval()

时间:2016-11-16 21:41:37

标签: javascript node.js

如果我从现在起10秒后调用setTimeOut(),然后执行一组长时间运行的命令,Node.js / JavaScript是否一直等到这些命令完成执行setTimeOut中设置的功能? setInterval()也是如此吗?

如果我在代码中起诉setTimeOut()和setInterval(),并且任务最终可能会在同一时间内执行,那么还有什么需要注意的吗?

我正在使用node-cron(https://github.com/kelektiv/node-cron/blob/master/lib/cron.js)库,我发现它使用了setTimeOut。我正在尝试使用setInterval()添加一些任务。

2 个答案:

答案 0 :(得分:2)

无法保证在准确的时间调用node.js中的计时器事件。

  

如果我从现在起10秒后调用setTimeOut(),则执行a   一组长时间运行的命令,Node.js / JavaScript会等到那些   命令完成执行setTimeOut中设置的功能?

是的,它等待,直到当前在node.js中执行的代码完成才能提供下一个计时器事件。

  

setInterval()也是如此吗?

是的,setInterval()的机制相同。

这里有一些关于node.js系统如何工作的解释。

node.js是一个单线程事件驱动系统(技术上线程在node.js中使用,但它只运行JS代码的一个单独线程)。

当您使用setTimeout()setInterval() node.js内部的某些内部机制时,系统计时器会知道下一个计时器何时应该触发。此时,会将事件插入node.js事件队列。如果node.js当时没有执行任何操作,则立即触发事件并立即调用相应的回调函数。

但是,如果node.js忙于运行代码,并且如果事件队列中的timer事件前面有其他事件,则不会立即触发timer事件。

相反,node.js将等待,直到node.js中的当前执行线程完成,然后,只有这样,事件队列中的下一个事件才会被拉出,并且将调用该事件的相应回调

所以,如果你有一些长期运行的node.js代码,它将阻止所有其他事件(包括计时器事件),直到它完成并且node.js可以回到将事件队列中的下一个事件拉出来

答案 1 :(得分:0)

答案是:也许但可能不是。

当事情是异步时,并不一定能保证什么时候会被调用。当异步事件被调用时,它将被添加到内部队列并且它将处理队列。可能性很大,他们会完成,但这不是你应该依赖的东西。

相反,你应该做的是触发一些事情来明确表明它已经完成。有很多方法可以解决它,例如回调和Promises。您甚至可以设置一个指示状态的布尔值,并在依赖步骤之前检查它。

let aDone = false;

setTimeout(() => { aDone = true; }, 1000);

const startInterval = () => {
    if (!aDone) {
        setTimeout(startInterval, 200); // try again in 200ms
    }

    setInterval(() => { /* do something */ }, 1000);
};

startInterval(); // kick off the interval check