node.js如何回调异步?

时间:2012-05-29 06:12:18

标签: javascript node.js

我最近开始使用node.js.它引用了node.js异步行为可以通过三种方式使用eventsstreamcallback

事件和流工作emit,pipe事件使其真正异步,但回调异步如何,因为执行在函数返回之前,除非 process.nextTick() 使用。

活动:

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

});

回调:

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

3 个答案:

答案 0 :(得分: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);
}

答案 1 :(得分: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(); 
        });
    });
    

答案 2 :(得分: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()的情况,从而导致不同的应用程序逻辑。