2012-05-29 137 views
1

我最近開始使用node.js.它引用了node.js的異步行爲可以用三種方式使用events,stream,callbacknode.js回調如何異步?

活動和emit,pipe事件使它真正異步流工作,但如何回調異步的,因爲它,除非使用process.nextTick()函數返回之前執行

活動:

event.on('data',function(data){ 

}); 

回調:

function(data,cb){ 
// do something with "data" 
cb(); 
return; 
} 

回答

1

讓我們來看看你的函數仔細一看,有一個回調:

function(data, cb) { 
// do something with "data" 
cb(); 
return; 
} 

您這裏有2個大錯誤:

1)當你有回調函數時,你沒有理由使用return。只有當你有立即發送響應的同步動作(他們不必等待未來某個時候觸發回調)時才使用返回。

2)您不立即執行回調,它沒有任何意義。你要麼不使用回調函數,而要使用return語句(當你真的沒有異步函數時),或者你在將來某個時候執行回調函數時,你會得到結果。

更好的例子:

function (data, cb) { 
    // you make an Ajax call and 
    // you don't know when the callback will be triggered 
    makeAjaxCall(data, cb); 
} 
+0

您可以非常合理的回報的東西與異步操作,例如你可以返回'this'以允許方法鏈接。 – lanzz

+0

@lanzz:儘管聽起來像是一個很好的比賽條件。 –

+0

@MichaelBorgwardt我認爲在事件驅動的單線程代碼中會導致競爭條件是非常麻煩的。另外,object.method1()。method2()比object.method1()更容易出現競爭條件。 object.method2()'? – lanzz

0

在這種情況下,回調函數沒有被異步運行,但仍有一些這樣的功能可以異步使用情況:

function foo(data, callback) { 
    // do something with the data 
    callback(); 
} 

function bar() { 
    // this will be called as a callback from foo() 
} 

setInterval(function() { foo(data, bar) }, 1000); 
console.log('this is displayed immediately'); 

你可以看到foo()計劃每秒運行一次,並且這是異步發生的;然而,回調的存在使您可以從foo()函數外設置額外的行爲,例如,您可能會設置幾個不同的回調調用foo()的情況,導致不同的應用程序邏輯。

1

你是正確的,回調不一定意味着異步I/O。

活動不一定是異步兩種,在這個意義上,EventEmitter的.emit立即生效,而不是在一個信用:

var EventEmitter = require('events').EventEmitter; 

var emitter = new EventEmitter(); 

emitter.on('ev', function(x) { 
    console.log("received event ", x); 
}); 

console.log("Hello"); 
emitter.emit('ev', "X"); 
console.log("World"); 

結果:

Hello 
received event X 
World 

然而,回調可以通過以下方式製成「異步」:

  • 使用process.nextTick()。這不會使回調異步中的實際I/O操作成爲現實。它只是推遲執行,直到下一個勾號。如果有些操作塊,事件循環也會阻塞 - 在下一個滴答而不是這個滴答。

    function(data, cb) { 
        process.nextTick(function() { doSomethingWith(data); cb(); }) 
    }); 
    
  • 呼叫從已知通過使用已知爲異步另一個基於回調的函數異步I/O操作

    function(data, cb) { 
        emitter.startIO(); 
        emitter.on('someIOEvent', function(e) { 
         doSomethingWith(data,e); 
         cb(); 
        }); 
    }); 
    
  • 被觸發的事件的指定的回調函數。節點核心和節點模塊中的大多數功能都是這樣的。

    function(data, cb) { 
        otherFunction(data, function(moredata) { 
         doMoreStuffWith(moredata, data); cb(); 
        }); 
    });