如何创建一个等待Javascript事件的异步函数?

时间:2018-12-23 01:40:00

标签: javascript node.js

如何阻止该事件?

const EventEmitter = require('events').EventEmitter;
const util = require('util');

function Task() {
    EventEmitter.call(this);
    this.setMaxListeners(Infinity);

    this.dosomething = () => {
    console.log("do something");
    };

    this.run = (iter) => {
    for(i = 0; i < iter; i++) {
            this.dosomething();
        this.emit('someevent');
    }
    }

}

util.inherits(Task, EventEmitter);

task = new Task();

function do_work() {
    console.log("work 1");
    task.once('someevent', (props) => {
    console.log('event happened');
    });
    console.log("work 2");
}

do_work();
task.run(5);

实际结果
工作1
工作2
做某事
事件发生了
做某事
做某事
做某事
做某事

预期结果
工作1
做某事
事件发生了
工作2
做某事
做某事
做某事
做某事

1 个答案:

答案 0 :(得分:3)

如果我正确理解了您的问题,则可以通过包装Promise事件处理程序的task来实现:

async function do_work() {

  console.log("work 1");

  // use a promise to block completion of do_work() function
  // until task event callback has been invoked
  await (new Promise(resolve => {

    task.once('someevent', (props) => {

      console.log('event happened');

      // Now that task callback has been invoked, "resolve" the
      // enclosing promise to allow do_work()'s execution to complete
      resolve();

    });
  }));

  console.log("work 2");
}

上面的代码中的想法是包装任务someevent处理程序,以便一旦事件处理程序触发后即可以调用诺言resolve(即,通过调用resolve())。这样可以恢复对do_work()的调用,以实现所需的执行行为。

此外,您将需要执行以下操作:

// Because do_work() is async, and becase you want to ensure that
// do_work() completes before starting task.run(5), you need to enclose
// these in an async function, eg doWorkThenRunTasks()
async function doWorkThenRunTasks() {

  // Call do_work asynchronously
  await do_work()

  // task.run will happen after do_work completed
  task.run(5);
}

doWorkThenRunTasks();

通过添加异步doWorkThenRunTasks()函数,您可以在完成await之后使用与do_work()相关的task.run(5)来强制执行do_work()的执行顺序。

希望这会有所帮助!