1

我最近开始使用 node.js。它引用了 node.js 异步行为可以以三种方式使用events,,,streamcallback

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

事件:

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

});

打回来:

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

3 回答 3

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(); 
        });
    });
    
于 2012-05-29T11:42:57.667 回答
1

让我们仔细看看有回调的函数:

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

您在这里有两个大错误:

1)当你有回调函数时,你没有理由使用 return 。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);
}
于 2012-05-29T06:29:46.810 回答
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()使用不同回调调用的情况,从而导致不同的应用程序逻辑。

于 2012-05-29T07:43:29.900 回答