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

sla*_*oco 9 javascript loops callback while-loop node.js

知道当Node.js异步工作时,写下这样的东西:

function sleep() {
    var stop = new Date().getTime();
    while(new Date().getTime < stop + 15000) {
        ;
    }
}

sleep();
console.log("done");
Run Code Online (Sandbox Code Playgroud)

...会调用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");
Run Code Online (Sandbox Code Playgroud)

所以我认为这将打印'DONE'并在15秒后打印出来.'done sleeping',因为sleep()函数被调用并被传递给回调函数的指针.当这个函数工作时(while循环),最后一行将被执行(print'add').15秒后,当sleep()函数完成时,它会调用给定的回调函数,然后打印"完成睡眠".

显然我在这里理解错误,因为上述两种方式都阻止了.有人可以澄清一下吗?

提前谢谢,Slagjoeyoco

Mah*_*ahn 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");
});
Run Code Online (Sandbox Code Playgroud)

  • @FabiánH.jr.关键是OP可能有兴趣理解为什么他的'while`不工作以及怎么能以一种非阻塞的方式写一个'while`,这是一个更好的答案,而不是"你的方法无关紧要不起作用,用其他方式代替". (4认同)

Abd*_*aly 9

你正在呼叫sleep,新sleep功能阻止.它一直在迭代,直到满足条件.您应该使用setTimeout()以避免阻止:

setTimeout(function () {
    console.log('done sleeping');
}, 15000);
Run Code Online (Sandbox Code Playgroud)