用EventEmitter编写asynchronous函数

我是新的节点,并尝试在节点中使用asynchronous和事件行为优点。 我曾经从节点了解到,所有与Event对象一起处理的东西,都是asynchronous执行。
然后我试试这个,考虑下面的代码:

var events = require("events"); var event = new events.EventEmitter(); event.on("work", function () { for (var i = 0; i <= 10; i++) { console.log("I do my work " + i); } event.emit("done"); }); var async = function (cb) { event.on("done", cb); event.emit("work"); for (var i = 0; i <= 10; i++) { console.log("Async " + i); } } async(function () { console.log("I am done callback!"); }); 

这是asynchronous执行? 在我看来不行! 为什么,因为我读了这么多句子:

一个事件被解雇了,所以去做一件事,然后当你完成它时,回来告诉我,但同时我会做别的。

就像一个快餐店的场景。 但是上面的代码,当事件工作要开始的时候,下面的序列将会发生:

  1. 进入callback
  2. 让循环
  3. 输出我做我的工作n
  4. 解雇了完成的事件
  5. 输出我完成callback!
  6. 输出asynchronous

为什么我做了callback! 会在Async n之前输出? 为什么这里不像快餐店的情景,就像

工作事件被解雇,去做你的东西,当你完成后回来,同时我会输出Async n

这是我用来了解事件驱动的行为和节点中的asynchronous。 但是现在我很困惑。 我知道,JavaScript在单线程上工作。 我怎样才能写事件发射器的asynchronousfunction? 但我认为是不可能的,因为当我发出一个事件,它会立即执行处理程序。

我曾经从节点了解到,所有与Event对象一起处理的东西,都是asynchronous执行。

这是不正确的。 事件是同步的。 当你添加一个监听器时,你只需要将callback保存在一个对象中:

 this._events[type].push(listener); 

当你发出一个事件,你只是迭代一个数组,并调用每个监听器:

 for (i = 0; i < len; i++) listeners[i].apply(this, args); 

源代码: https : //github.com/joyent/node/blob/master/lib/events.js

这是asynchronous执行? 在我看来不行!

你是对的。 如果您调用任何I / O函数或使用setImmediatenextTick或一个计时器,则是asynchronous的,否则它是同步的。 asynchronous写入的同步代码不会将其转换为asynchronous代码。

为什么我做了callback! 会在Async n之前输出?

因为当你收到“完成”callback你调用“cb”:

 event.on("done", cb); 

cb返回时,执行“Async n”循环。

我怎样才能写事件发射器的asynchronousfunction?

使用setImmediateprocess.nextTick

如果你想推迟“我做我的工作”循环执行,你可以用events.emit ("work")包装行events.emit ("work")

 var events = require("events"); var event = new events.EventEmitter(); event.on("work", function () { for (var i = 0; i <= 10; i++) { console.log("I do my work " + i); } event.emit("done"); }); var async = function (cb) { event.on("done", cb); process.nextTick (function () { //<----- event.emit("work"); }); //<----- for (var i = 0; i <= 10; i++) { console.log("Async " + i); } } async(function () { console.log("I am done callback!"); }); 

这将打印:

 Async 0 Async 1 Async 2 Async 3 Async 4 Async 5 Async 6 Async 7 Async 8 Async 9 Async 10 I do my work 0 I do my work 1 I do my work 2 I do my work 3 I do my work 4 I do my work 5 I do my work 6 I do my work 7 I do my work 8 I do my work 9 I do my work 10 I am done callback!