我进行了大量搜索,尝试找出如何在 Node.js 中创建非阻塞代码。不幸的是,我发现的每个示例都基于一个函数,该函数最终已经具有内置回调。所以我想用回调创建自己的函数,但由于某种原因它阻止了事件循环。这并没有阻止事件循环:
function foo(response){
setTimeout(function(){
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("bar");
response.end();
}, 7000);
}
但这做到了:
function foo(response){
function wait(callback, delay){
var startTime = new Date().getTime();
while (new Date().getTime() < startTime + delay);
callback();
}
wait(function(){
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("bar");
response.end();
}, 7000);
}
我缺少非阻塞代码的哪些基本方面?
Edit:
我重新创建 setTimeout 的目标更多的是一种心理练习,我想我会尝试这样我可以更好地理解偶数循环。现在我担心如果我有一些相当重的服务器端代码在 JavaScript 中进行一些原始处理,我将不知道如何阻止它停止我的事件循环。
在阅读了您的答案并进一步思考后,我认为更准确的问题可能是这样的:如果我使用 JavaScript 在服务器上进行繁重的处理,如何阻止它中断事件循环?
这是我第一次在这里发帖,所以我不知道我会得到什么样的回应。到目前为止,这非常棒。多谢你们。
Edit 2:嘿嘿,再次感谢大家的建议。我最终尝试了 process.nextTick 就像 Raynos 建议的那样......并且它起作用了!我设法用回调创建了自己的非阻塞计时器。该代码并不完美,但对于那些好奇的人来说,它是这样的:
var timer = {};
function delay(callback, length){
if(!timer.startTime){
timer.startTime = new Date().getTime();
timer.callback = callback;
timer.length = length;
}
if(new Date().getTime() < timer.startTime + timer.length){
process.nextTick(delay);
} else {
timer.callback();
timer = {};
}
}
function list(response){
delay(function(){
console.log("callback");
exec("dir", function (error, stdout, stderr) {
response.writeHead(200, {"Content-Type": "text/plain"});
response.write(stdout);
response.end();
});
}, 7000);
}
并不是真的打算使用这段代码。但学习如何做到这一点的过程确实帮助我理解了非阻塞的一些关键概念。
对于那些仍然对非阻塞感到好奇的人,您应该查看一下雷诺斯的文章。 http://raynos.org/blog/13/What-it-means-to-be-non-blocking-in-node.