node.js:while循环回调未按预期工作

时间:2012-10-13 00:22:09

标签: javascript node.js loops callback while-loop

知道当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

4 个答案:

答案 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/