如果我从现在起10秒后调用setTimeOut(),然后执行一组长时间运行的命令,Node.js / JavaScript是否一直等到这些命令完成执行setTimeOut中设置的功能? setInterval()也是如此吗?
如果我在代码中起诉setTimeOut()和setInterval(),并且任务最终可能会在同一时间内执行,那么还有什么需要注意的吗?
我正在使用node-cron(https://github.com/kelektiv/node-cron/blob/master/lib/cron.js)库,我发现它使用了setTimeOut。我正在尝试使用setInterval()添加一些任务。
答案 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