javascript node.js:while 循环回调未按预期工作
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12868804/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
node.js: while loop callback not working as expected
提问by slagjoeyoco
Knowing that while Node.js is working asynchronously, writing something like this:
知道 Node.js 是异步工作的,写这样的东西:
function sleep() {
var stop = new Date().getTime();
while(new Date().getTime < stop + 15000) {
;
}
}
sleep();
console.log("done");
...would call the sleep(), block the server for the duration of the while loop (15secs) and just THEN print "done" to the console. As far as I understand, this is because Node.js is giving JavaScript only access to the main thread, and therefore this kidn of thing would halt further execution.
...将调用 sleep(),在 while 循环期间(15 秒)阻塞服务器,然后将“完成”打印到控制台。据我了解,这是因为 Node.js 只允许 JavaScript 访问主线程,因此这种东西会停止进一步的执行。
So I understand the solution to this is to use callbacks:
所以我理解解决这个问题的方法是使用回调:
function sleep(callback) {
var stop = new Date().getTime();
while(new Date().getTime() < stop + 15000) {
;
}
callback();
}
sleep(function() {
console.log("done sleeping");
});
console.log("DONE");
So I thought this would print 'DONE' and after 15 secs. 'done sleeping', since the sleep() function gets called and is handed a pointer to a callback function. While this function is working (the while loop), the last line would be executed (print 'done'). After 15 seconds, when the sleep() function finishes, it calls the given callback function, which then prints 'done sleeping'.
所以我认为这会在 15 秒后打印“完成”。'done sleep',因为 sleep() 函数被调用并被传递一个指向回调函数的指针。当这个函数运行时(while 循环),最后一行将被执行(print 'done')。15 秒后,当 sleep() 函数完成时,它调用给定的回调函数,然后打印“done sleep”。
Apparently I understood something wrong here, because both of the above ways block. Can anybody clarify please?
显然我在这里理解错了,因为上述两种方式都阻止了。有人可以澄清吗?
Thanks in advance, Slagjoeyoco
提前致谢, Slagjoeyoco
回答by Mahn
Javascript and node.js are single threaded, which means a simple while
blocks; no requests/events can be processed until the while
block is done. Callbacks don't magically solve this problem, they just help pass custom code to a function. Instead, iterate using process.nextTick
, which will give you esentially the same results but leaves space for requests and events to be processed as well, ie, it doesn't block:
Javascript 和 node.js 是单线程的,这意味着一个简单的while
块;在while
块完成之前,不能处理任何请求/事件。回调并不能神奇地解决这个问题,它们只是帮助将自定义代码传递给函数。相反,迭代 using process.nextTick
,这将给您本质上相同的结果,但也为要处理的请求和事件留出空间,即它不会阻塞:
function doSleep(callback) {
var stop = new Date().getTime();
process.nextTick(function() {
if(new Date().getTime() < stop + 15000) {
//Done, run callback
if(typeof callback == "function") {
callback();
}
} else {
//Not done, keep looping
process.nextTick(arguments.callee);
}
});
}
doSleep(function() {
console.log("done sleeping");
console.log("DONE");
});
回答by Abdullah Jibaly
You are calling sleep
right away, and the new sleep
function blocks. It keeps iterating until the condition is met. You should use setTimeout()
to avoid blocking:
您正在立即调用sleep
,以及新的sleep
功能块。它不断迭代,直到满足条件。您应该使用setTimeout()
以避免阻塞:
setTimeout(function () {
console.log('done sleeping');
}, 15000);
回答by Ry-
Callbacks aren't the same thing as asynchronicity, they're just helpful when you want to get a... callback... from an asynchronous operation. In your case, the method still executes synchronously; Node doesn't just magically detect that there's a callback and long-running operation, and make it return ahead of time.
回调与异步性不同,它们只是在您想从异步操作中获得......回调......时很有帮助。在您的情况下,该方法仍然同步执行;Node 不仅会神奇地检测到有回调和长时间运行的操作,并使其提前返回。
The realsolution is to use setTimeout
instead of a busy loop on another thread.
在真正的解决方案是使用setTimeout
的,而不是在另一个线程繁忙的循环。
回答by skovalyov
As already mentioned, asynchronous execution should be achieved by setTimeout() rather than while, because while will freeze in one "execution frame".
如前所述,异步执行应该通过 setTimeout() 而不是 while 来实现,因为 while 会冻结在一个“执行帧”中。
Also it seems you have syntax error in your example.
此外,您的示例中似乎有语法错误。
This one works fine: http://jsfiddle.net/6TP76/
这个工作正常:http: //jsfiddle.net/6TP76/