知道当Node.js异步工作时,写下这样的东西:
function sleep() {
var stop = new Date().getTime();
while(new Date().getTime < stop + 15000) {
;
}
}
sleep();
console.log("done");
...将调用sleep(),在while循环(15secs)期间阻止服务器,然后打印“完成”到控制台。据我所知,这是因为Node.js只允许JavaScript访问主线程,因此这个东西会停止进一步执行。
所以我理解这个解决方案是使用回调:
function sleep(callback) {
var stop = new Date().getTime();
while(new Date().getTime() < stop + 15000) {
;
}
callback();
}
sleep(function() {
console.log("done sleeping");
});
console.log("DONE");
所以我认为这将打印'DONE'并在15秒后打印出来。 'done sleeping',因为sleep()函数被调用并被传递给回调函数的指针。当这个函数工作时(while循环),最后一行将被执行(print'add')。 15秒后,当sleep()函数完成时,它会调用给定的回调函数,然后打印“完成睡眠”。
显然我在这里理解错误,因为上述两种方式都阻止了。有人可以澄清吗?
提前致谢, Slagjoeyoco
答案 0 :(得分:13)
Javascript和node.js是单线程的,这意味着一个简单的while
块;在while
块完成之前,不能处理任何请求/事件。回调并没有神奇地解决这个问题,它们只是帮助将自定义代码传递给函数。相反,使用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");
});
答案 1 :(得分:9)
您正在立即调用sleep
,新的sleep
功能块。它一直在迭代,直到满足条件。您应该使用setTimeout()
来避免阻止:
setTimeout(function () {
console.log('done sleeping');
}, 15000);
答案 2 :(得分:2)
回调与异步性不同,当你想从异步操作获得...回调时,它们只是有用的。在您的情况下,该方法仍然同步执行; Node不仅神奇地检测到有回调和长时间运行的操作,而是让它提前返回。
真正的解决方案是在另一个线程上使用setTimeout
而不是繁忙的循环。
答案 3 :(得分:0)
如前所述,异步执行应该通过setTimeout()而不是while来实现,因为while会冻结在一个“执行帧”中。
您的示例中似乎也有语法错误。
这个工作正常:http://jsfiddle.net/6TP76/