2013-12-19 48 views
-1
function f(cb) { 
    console.log("f's activity starts."); 
    var t = Math.random() *5000; 
    function onActivityDone() { 
     console.log("f's activity ends."); 
     if (cb) cb(); 
    } 
    setTimeout(onActivityDone, t); 
} 

f(); 
f(); 
f(); 

console.log(); 

我用這個函數做回調,任務是不修改'f'函數。 的輸出要求是這樣的:Callback node.js

f's activity starts. 
f's activity starts. 
f's activity starts. 
f's activity ends. 
f's activity ends. 
f's activity ends. 
Done. 

但由於某些原因,我一直在歌廳

f's activity starts. 
f's activity starts. 
f's activity starts. 
Done. 
f's activity ends. 
f's activity ends. 
f's activity ends. 

任何想法發生了什麼?

+0

我猜console.log();意味着'完成'? –

+7

異步功能的力量! – BeNdErR

+0

發電機的威力! – Florent

回答

1

它既是異步的也是非阻塞的。你期望的是阻止行爲(f塊console.log)。 f和console.log都是普通函數,不會互相阻塞。

阻塞函數被認爲是不好的。它使正在執行的進程/線程等待。這是等待OS安排其他線程。

0

setTimeout()觸發你的回調函數異步:http://nodejs.org/docs/v0.6.1/api/timers.html#setTimeout

如果你想運行後,對方這些功能,那麼你就必須使用回調(因爲你已經在f()期待)。然後,你可以打電話給他們這樣的:

f(f.bind(this, f)) 

或者你可以使用一些小流量控制庫一樣runnelasync(這是一個有點臃腫)

0

看看Mixu的書here。特別是他在第7.3節中的一系列任務的註釋(在這裏複製以便參考)。

function series(callbacks, last) { 
    var results = []; 
    function next() { 
    var callback = callbacks.shift(); 
    if(callback) { 
     callback(function() { 
     results.push(Array.prototype.slice.call(arguments)); 
     next(); 
     }); 
    } else { 
     last(results); 
    } 
    } 
    next(); 
} 
// Example task 
function async(arg, callback) { 
    var delay = Math.floor(Math.random() * 5 + 1) * 100; // random ms 
    console.log('async with \''+arg+'\', return in '+delay+' ms'); 
    setTimeout(function() { callback(arg * 2); }, delay); 
} 
function final(results) { console.log('Done', results); } 

series([ 
    function(next) { async(1, next); }, 
    function(next) { async(2, next); }, 
    function(next) { async(3, next); }, 
    function(next) { async(4, next); }, 
    function(next) { async(5, next); }, 
    function(next) { async(6, next); } 
], final);