繁体   English   中英

node.js setTimeout()是否正常工作?

[英]Is node.js setTimeout() working?

我是Node.js的新手。 我需要做些什么才能使setTimeout()工作吗?

这是一个代码片段。

完成后将appMsg.doneLoadTables = true设置的异步代码

do {
  console.log('waiting ...   ' + appMsg.doneLoadTables);
  setTimeout(function() { console.log('waiting ...'); }, 1000);
} while (!appMsg.doneLoadTables);

症状:

  • (虽然对console.log的两个调用是相似的,但只有第一个会打印appMsg.doneLoadTables的值。)每个结果都包含该值。
  • 两次调用console.log的间隔比1000毫秒小得多。 (我怀疑间距与计算机可以处理此处所示循环的速度一样快。)
  • 虽然我希望异步例程可以在我在此指定的延迟期间继续处理,但我从未见过这样的循环; 好像该循环占用了所有处理资源,并阻止了异步例程完成其工作并阻止了将结束该循环的变量。

我对Node 4.2.1有此经验; 安装Node 5.0.0后,我仍然有这种体验。

我已经看到关于setTimeout()的类似问题在这里已经问过很多次了。 我希望我在setTimeout()中使用IIFE可以使这个问题与所有问题区分开。

在此先感谢您提供的任何帮助...

JavaScript是单线程的。 setTimeout 不是一种sleep形式,它会在该行暂停代码。 它的工作方式是“安排”回调以供以后使用,并在堆栈耗尽(引擎不执行任何操作)且至少n毫秒后执行时执行,其中n是您放置的延迟(以毫秒为单位)。

现在您的代码不起作用,因为它永远不会退出循环。 该代码没有机会执行其他代码(您希望运行并更改appMsg.doneLoadTables的值的代码)。 它所做的全部工作都会记录“正在等待... [某物]”。

本质上,您正在轮询。 您可以使用setInterval代替。 appMsg.doneLoadTablestrue ,可以使用clearInterval停止轮询。

我不是100%确定您的目标是什么...但是,也许此代码段将您带到了想要去的地方(我选择了setTimeout而不是setInterval ):

var appMsg = {doneLoadTables: false};

var stillLoading = function() {
    if(false === appMsg.doneLoadTables) {
        console.log('waiting ...   ' + appMsg.doneLoadTables);
        setTimeout(stillLoading, 50);
    }
    else {
        console.log('Loading complete.');
        process.exit();
    }
}

stillLoading();
setTimeout(function(){
    console.log('Setting appMsg.doneLoadTables = true');
    appMsg.doneLoadTables = true;
}, 1000);

该脚本每50毫秒轮询一次状态,并在1秒后精确标记为“完成”。

输出看起来像这样

waiting ...   false
waiting ...   false
waiting ...   false
waiting ...   false
...
Setting appMsg.doneLoadTables = true
Loading complete.

(虽然对console.log的两个调用是相似的,但只有第一个会打印appMsg.doneLoadTables的值。)每个结果都包含该值。

这是正确的行为,因为您永远不会退出while循环。 您将停留在永远循环的同一事件框架中。

两次调用console.log的间隔比1000毫秒小得多。 (我怀疑间距与计算机可以处理此处所示循环的速度一样快。)

这再次是正确的行为,因为传递给setTimeout的回调将永远不会执行,除非退出从未执行的do-while循环。 因此,您只需继续调用第一个console.log语句,然后将回调添加到事件循环即可在1000毫秒内执行,而不会给它(您传递的回调)执行的机会。

虽然我希望异步例程可以在我在此指定的延迟期间继续处理,但我从未见过这样的循环; 好像该循环占用了所有处理资源,并阻止了异步例程完成其工作并阻止了将结束该循环的变量。

循环永远不会结束,因为没有实现该循环的逻辑。 “异步例程”无法继续,因为这将需要退出当前事件框架(运行无限循环),并开始下一个将您回调传递给setTimeout的事件框架。

希望我的解释将帮助您了解异步JavaScript的工作方式。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM