admin管理员组文章数量:1323330
I've done a lot of searching to try and find out how to create non-blocking code in Node.js. Unfortunately, every example I've found is grounded to a function that, in the end, already has a built in callback. So I wanted to create my own function with a callback, but for some reason it blocks the event loop. This didn't block the event loop:
function foo(response){
setTimeout(function(){
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("bar");
response.end();
}, 7000);
}
But this did :
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);
}
What fundamental aspect of non-blocking code am I missing?
Edit:
My goal to recreate setTimeout is more of a mental exercise I thought I'd try so I can understand the even loop a little better. Right now I'm worried that if I have some rather heavy server side code that's doing some raw processing in JavaScript, I won't know how to stop it from halting my event loop.
After reading your answers and thinking about this a bit further, I think a more accurate question would probably be this: If I'm doing heavy processing on my server with JavaScript, how do I stop that from interrupting the event loop?
It's my first time posting on here, so I didn't know what kind of response I was gonna get. So far, this is awesome. Thanks, guys.
Edit 2: Hey, so thanks again everyone for the advice. I ended up trying out process.nextTick like Raynos suggested... and it worked! I managed to create my own non-blocking timer with a callback. The code isn't perfect, but for those who are curious, this is how it looks:
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);
}
Not really intending to use this code. But the process of learning how to do this definitely helped me understand some key concepts about non-blocking.
And for those of you still curious about non-blocking, you should check out Raynos' article.
I've done a lot of searching to try and find out how to create non-blocking code in Node.js. Unfortunately, every example I've found is grounded to a function that, in the end, already has a built in callback. So I wanted to create my own function with a callback, but for some reason it blocks the event loop. This didn't block the event loop:
function foo(response){
setTimeout(function(){
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("bar");
response.end();
}, 7000);
}
But this did :
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);
}
What fundamental aspect of non-blocking code am I missing?
Edit:
My goal to recreate setTimeout is more of a mental exercise I thought I'd try so I can understand the even loop a little better. Right now I'm worried that if I have some rather heavy server side code that's doing some raw processing in JavaScript, I won't know how to stop it from halting my event loop.
After reading your answers and thinking about this a bit further, I think a more accurate question would probably be this: If I'm doing heavy processing on my server with JavaScript, how do I stop that from interrupting the event loop?
It's my first time posting on here, so I didn't know what kind of response I was gonna get. So far, this is awesome. Thanks, guys.
Edit 2: Hey, so thanks again everyone for the advice. I ended up trying out process.nextTick like Raynos suggested... and it worked! I managed to create my own non-blocking timer with a callback. The code isn't perfect, but for those who are curious, this is how it looks:
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);
}
Not really intending to use this code. But the process of learning how to do this definitely helped me understand some key concepts about non-blocking.
And for those of you still curious about non-blocking, you should check out Raynos' article.
Share edited Jan 21, 2012 at 8:05 Craig asked Jan 21, 2012 at 0:03 CraigCraig 531 silver badge6 bronze badges 6-
2
bodyless while loop
... "What fundamental aspect of non-blocking code am I missing?" – Alex Wayne Commented Jan 21, 2012 at 0:22 -
You shouldn't be trying to recreate
setTimeout
, just use it. It was made for this purpose. – david Commented Jan 21, 2012 at 0:24 - I guess the idea was to more deeply understand what setTimeout does to keep the event loop going. My hope is that I could then use the same method if I had to do heavy processing with JavaScript server-side. – Craig Commented Jan 21, 2012 at 0:28
-
why do you want to do your own
setTimeout
? your code will just get stucked in thatwhile
. and javascript has nosleep
– Hugo Mota Commented Jan 21, 2012 at 0:28 - 1 What it means to be non blocking in node – Raynos Commented Jan 21, 2012 at 1:09
4 Answers
Reset to default 4In order to not block the event loop your code has to eventually return to the event loop and allow it to continue processing. Unless your code actually returns to the event loop then it can't dequeue the next message and process it. This code won't exit for the given time period and hence never returns control to the event loop.
You've got most of the correct idea - you want to write a function that will execute quickly and then return control back to the main event loop. Instead of the function itself idly waiting (in your case by literally sitting in a while loop and sleeping), it registers a callback -- typically with setTimeout -- and then returns. Then, when the timeout is called it wakes back up and executes whatever function it needs to.
function foo(response){
function wait(callback, delay){
var startTime = new Date().getTime();
// this will block the event loop until this condition is true
while (new Date().getTime() < startTime + delay);
//then the callback is called
callback();
//then it goes back to the event loop
}
wait(function(){
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("bar");
response.end();
}, 7000);
}
maybe a wrapper is what you want?
function wait(callback, delay){
setTimeout(callback, delay);
}
When you call a function you don't start a new thread. Therefore running a while loop inside the wait function will block execution.
本文标签:
版权声明:本文标题:javascript - Node.js: How would you recreate the 'setTimeout' function without it blocking the event loop? - Sta 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742139174a2422504.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论