2017-08-06 44 views
0

這裏是例子:我很困惑與定時器和異步I/O中的Node.js

const http = require('http'); 

let startTime = Date.now(); 

http.createServer((req,res)=>{ 
    console.log('hello'); 
    res.end('nice'); 
}).listen(8888,()=>{ 
    console.log('server listened at port 8888'); 
}); 


setTimeout(function() { 
    console.log('hei,I am 5000 timeout function' + `time past ${Date.now()-startTime}`); 
}, 5000); 

setImmediate(()=>{ 
    console.log('hei,I am immediate function' + `time past ${Date.now()-startTime}`); 
}) 

結果:

server listened at port 8888 
hei,I am immediate functiontime past 14 
hei,I am 5000 timeout functiontime past 5016 

但在我的思想,setImmediate回調應該運行5000ms後,因爲http異步網絡I/O應該阻止事件循環5000ms,因爲超時由setTimeout設置。但結果表明,I/O pool階段的事件循環立即返回。爲什麼?代碼事件循環:

timeout = 0; 
    if ((mode == UV_RUN_ONCE && !ran_pending) || mode == UV_RUN_DEFAULT) 
     timeout = uv_backend_timeout(loop); 

    uv__io_poll(loop, timeout); 
    uv__run_check(loop); 

uv_backend_timeout()

diff = handle->timeout - loop->time; 
    if (diff > INT_MAX) 
    diff = INT_MAX; 

    return diff; 

所以I/O pool超時應該是5000毫秒,然後uv_epoll_wait()應該阻止對5000毫秒事件循環,然後去check階段。所以我很困惑爲什麼setImmediate回調運行得這麼早。

回答

0

setTimeout函數是nodejs中的非阻塞函數。它不會阻止主事件循環。如果你真的想阻止事件循環,那麼使用等待功能。