当前位置: 首页 > 面试题库 >

用EventEmitter编写异步函数

杜成和
2023-03-14
问题内容

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

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. 输出我做我的工作
  4. 触发完成事件
  5. 输出我完成回调!
  6. 输出异步n

为什么我要完成回调!要在异步n之前输出?为什么这里不像快餐店这样的场景

工作事件被触发,去做你的事情,做完后再回来,同时我将输出Async n

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


问题答案:

我以前从节点上了解到,用事件对象处理的所有内容都会异步执行。

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

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或定时器,否则,它是同步的。异步编写的同步代码不会将其转换为异步代码。

为什么我要完成回调!要在异步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!


 类似资料:
  • 问题内容: 我试图研究应如何精确地编写异步函数。经过大量的文档研究之后,我仍然不清楚。 如何为Node编写异步函数? 如何正确实施错误事件处理? 问我问题的另一种方式是:我应该如何解释以下功能? 问题答案: 您似乎将异步IO与异步功能混淆了。由于非阻塞IO更好,所以node.js使用异步非阻塞IO。理解它的最好方法是去观看ryan dahl的一些视频。 如何为Node编写异步函数? 只需编写普通函

  • 问题内容: 我们如何才能在传递给事件发射器的回调中结束函数 而又不使事件发射 器 散布 ? 另外,无需使用 外部模块 ,只需使用普通的 NodeJS 7.x / 8.x (支持 Es6 语法和。 我们基本上希望将an 与事件发射器混合使用,以便在事件发射器发出信号时解析它。 另外请记住,在使用其他异步功能完成之前,我们不会从事件发射器开始。 如果我们有一个“新的Promise(…)”,我们将调用r

  • 我正面临着一个问题,即设计能够执行网络I/O的方法(用于可重用库)。我读过这个问题 API设计中C#5Await/Async模式 以及其他与我的问题更接近的问题。 所以,问题是,如果我想同时提供异步和非异步方法,我必须如何设计这些? 例如,要公开方法的非异步版本,我需要执行如下操作 我觉得这不是个好设计。我想要一个关于如何定义私有方法的建议(例如),这些私有方法可以包装在公共方法中以提供两个版本。

  • 我在一个函数中有这样的代码块: 它获取一些数据,然后对数据运行验证()。 但是,我对数据的验证实际上也是异步的,因为它是根据一个json模式来验证数据的,而json模式位于一个独立的json文件中,所以它必须首先读取该文件。 我使用了一个承诺来读取文件内容,然后进行验证: 如何编辑此问题中的顶部代码块以解释if语句()中的异步函数?

  • 问题内容: 首先,这是一个非常特殊的情况,它以错误的方式故意将异步调用改型为一个非常同步的代码库,该代码库长成千上万行,并且当前时间不具备进行更改的能力。对的。” 它伤害了我的每一个生命,但是现实和理想往往并没有相互融合。我知道这很糟糕。 好的,顺便说一句,我该如何做,这样我可以: 示例(或缺少示例)全部使用库和/或编译器,这两种库均不适用于此解决方案。我需要一个如何使其冻结的具体示例(例如,在调

  • 问题内容: 我正在编写一个库,希望最终用户可以选择使用该库,就像其方法和功能不是协程一样。 例如,给定此功能: 最终用户不愿意在自己的代码中使用任何异步功能,仍然必须导入asyncio并运行以下命令: 如果可以的话,可以确定自己是否被称为协程,并做出相应的反应,这很酷。 所以像: 问题答案: 您需要两个函数-异步协程和同步常规函数: 实际上是,但我强烈建议您不要在同一函数中混合使用同步代码和异步代