用EventEmitter写异步函数

时间:2013-07-19 08:00:37

标签: javascript node.js asynchronous

我是节点中的新手并尝试在节点中使用异步和事件行为优势。我以前从节点了解到,处理Event对象的所有东西都会异步执行 然后我尝试了这个,考虑下面的代码:

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!");
});  

这是异步执行吗?在我看来没有!为什么,因为我读了很多这句话:

  

事件被触发,所以去做一些事情然后当你完成它时,来吧   回来告诉我,但同时我会做点别的。

像快餐店一样。但是上面的代码,当事件工作开始时,将按顺序发生:

  1. 进入回调
  2. 通过循环
  3. 输出我的工作n
  4. 解雇了已完成的事件
  5. 输出我完成了回调!
  6. 输出Async n
  7. 为什么我做完回调!要在Async n之前输出吗?为什么这里不喜欢快餐店的场景,比如

      

    工作事件被解雇了,你去做什么,然后回来   完成,同时我将输出Async n

    这是我习惯了解事件驱动的行为和节点中的异步。但现在我很困惑。我知道,javascript适用于单线程。如何用事件发射器编写异步函数?但我认为是不可能的,因为当我发出一个事件时,它会立即执行处理程序。

1 个答案:

答案 0 :(得分:21)

  

我曾经从节点理解,处理Event的所有东西   对象,它将是异步执行。

这是不正确的。事件是同步的。添加侦听器时,只需将回调保存在对象中:

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

  

这是异步执行吗?在我看来没有!

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

  

为什么我做完回调!要在Async n之前输出吗?

因为当你收到“完成”回调时,你会拨打“cb”:

event.on("done", cb);

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

  

如何用事件发射器编写异步函数?

使用setImmediateprocess.nextTick

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

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!