我最近开始使用node.js.它引用了node.js异步行为可以通过三种方式使用events
,stream
,callback
。
事件和流工作emit,pipe
事件使其真正异步,但回调异步如何,因为执行在函数返回之前,除非 process.nextTick() 使用。
活动:
event.on('data',function(data){
});
回调:
function(data,cb){
// do something with "data"
cb();
return;
}
答案 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()
的情况,从而导致不同的应用程序逻辑。