从Node.js事件处理程序到生成器

8fsztsew  于 2023-01-01  发布在  Node.js
关注(0)|答案(2)|浏览(125)

我有一个monitor对象,它通过一个事件处理程序在每次找到数据时引发一个事件:

monitor.on("data", data => { /* do something */ })

我想用一个生成器来替换这个模式:

for await(const data of monitor.iterate()) { /* do something */ }

我知道我能做到:

async function monitorWrapper() {
  const allData = await new Promise( resolve => {
    const _allData = []
    monitor.on("data", d => _allData.push(d))
    monitor.on("end", () => resolve(_allData))
  } )
  yield *allData
}

这样称呼它:

for await (const data of monitorWrapper()) { /* do something */ }

但这否定了使用yield的全部意义,因为我必须等待所有元素都可用后才能进行处理。

在这方面,我的问题是:是否有任何模式允许在触发data事件时让步?

gopyfrb3

gopyfrb31#

我自己也遇到了这个问题。

const stream = new class {      // mock event stream
  async start() {
    while (true) {
      const ms = Math.random() * 100;
      await new Promise(resolve => setTimeout(resolve, ms));
      if (this.handler) this.handler(ms);
    }
  }
  on(handler) { this.handler = handler; }
}

class Monitor {
  events = [];                  // store events
  resolve = () => {};           // resolves current outstanding promise
  constructor(handler) {
    handler(event => {          // binds event listener
      this.events.push(event);  // add event
      this.resolve();           // call resolve
    });
  }
  async *stream() {                                    // generator
    while (true) {
      let event;
      while (event = this.events.shift()) yield event; // remove and yield
      await new Promise(r => this.resolve = r);        // wait for next
    }
  }
}

const monitor = new Monitor(handler => stream.on(handler)); // bind events
stream.start();

for await (const event of monitor.stream()) { console.log({ event }); }
bqujaahr

bqujaahr2#

我不确定,但我想你可以试试这个,然后让我知道发生了什么。

//start is a thunk creator
    function start(cb){
        var c = cb();
        c.next(); //start up!
        return function(data){
            c.next(data);
        };
    }

    monitor.on('data', start(function(message){
        var m = yield message;
        console.log(m);
    }));

相关问题