javascript 使用 EventEmitter 编写异步函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17740988/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
write async function with EventEmitter
提问by zero_coding
I am new in node and try to use async and event behavior advantages in node. I used to understand from node, everything that handle with Event object, it gonna be async execution.
Then i had try this, consider following code:
我是节点的新手,并尝试在节点中使用异步和事件行为优势。我曾经从 node 中了解到,所有处理 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!");
});
This is async execution? In my opinion no! Why, because i had read this sentence many:
这是异步执行?在我看来没有!为什么,因为这句话我读过很多:
An event is fired, so go and do something and then when you have finished it, come back and tell me, but in meanwhile i will do something else.
一个事件被触发,所以去做一些事情,然后当你完成它时,回来告诉我,但与此同时我会做其他事情。
Like a fast food restaurant scenario. But the code above, when the event work gonna fired, following sequence will happen:
就像快餐店的场景。但是上面的代码,当事件工作被触发时,会发生以下序列:
- go into the callback
- let through the loop
- output I do my work n
- fired the done event
- output I am done callback!
- output Async n
- 进入回调
- 让通过循环
- 输出我做我的工作 n
- 触发 done 事件
- 输出我完成回调!
- 输出异步n
why I am done callback! gonna output before Async n? Why is here not like fast food restaurant scenario, like
为什么我完成回调!会在 Async n 之前输出吗?为什么这里不像快餐店的场景,像
the work event is fired, go and do you stuff and come back when you done, in meanwhile i will output Async n
工作事件被触发,去做你的事情并在你完成后回来,同时我将输出 Async n
This is i used to understand about event driven behavior and async in node. But now i am very confused. I know, javascript works on single thread. How can i write an async function with event emitter? But i think is not possible, because when i emit an event, it will immediately execute the handler.
这是我用来了解节点中的事件驱动行为和异步的。但现在我很困惑。我知道,javascript 在单线程上工作。如何使用事件发射器编写异步函数?但我认为这是不可能的,因为当我发出一个事件时,它会立即执行处理程序。
回答by Gabriel Llamas
I used to understand from node, everything that handle with Event object, it gonna be async execution.
我曾经从 node 中了解到,所有处理 Event 对象的事情都是异步执行的。
This is incorrect. Events are synchronous. When you add a listener, you're just saving the callback in an object:
这是不正确的。事件是同步的。添加侦听器时,您只是将回调保存在对象中:
this._events[type].push(listener);
When you emit an event, you're just iterating an array and calling each listener:
当您发出事件时,您只是在迭代一个数组并调用每个侦听器:
for (i = 0; i < len; i++)
listeners[i].apply(this, args);
Source code: https://github.com/joyent/node/blob/master/lib/events.js
源代码:https: //github.com/joyent/node/blob/master/lib/events.js
This is async execution? In my opinion no!
这是异步执行?在我看来没有!
You are correct. It's async if you call any I/O function or use setImmediate
, nextTick
or a timer—otherwise, it's synchronous. A synchronous code being written asynchrously doesn't convert it to an asynchrous code.
你是对的。它的异步,如果你调用任何I / O功能或使用setImmediate
,nextTick
或定时器,否则,它是同步的。异步编写的同步代码不会将其转换为异步代码。
why I am done callback! gonna output before Async n?
为什么我完成回调!会在 Async n 之前输出吗?
Because when you receive the "done" callback you call to "cb":
因为当您收到“done”回调时,您会调用“cb”:
event.on("done", cb);
When cb
returns, the "Async n" loop is executed.
当cb
返回时,“异步N”循环执行。
How can i write an async function with event emitter?
如何使用事件发射器编写异步函数?
Using setImmediate
or process.nextTick
.
使用setImmediate
或process.nextTick
。
If you want to postpone the "I do my work" loop execution, you can wrap the line events.emit ("work")
with 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!");
});
This will print:
这将打印:
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!