2012-05-29 138 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(); 
        }); 
    });