暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

发现一个有趣的方法:events.once

背井 2021-03-03
731

作为一个爱逛推特的人,经常能从别人的推文中发现好东西。之前有几篇文章也是受推文启发所写:


今天谈谈另一个发现:events
模块中的 once
函数。


推文下面的评论者是Node.js大神,既然连他都说了这个方法用的很多,我就更有兴趣了解下去了。

查看文档

来自官方文档(https://nodejs.org/api/events.html#events_events_once_emitter_name):

events.once(emitter, name)

Creates a Promise
that is fulfilled when the EventEmitter
emits the given event or that is rejected when the EventEmitter
emits 'error'
. The Promise
will resolve with an array of all the arguments emitted to the given event.

大意是该方法会返回一个 Promise
, 当监控的 EventEmitter
对象发布了给定name
的事件后,Promise
变成 resolved,且收到的参数是发布事件时传递的参数(以数组形式);而当EventEmitter
对象发布的是'error'
事件时,Promise
变成 rejected,收到的参数也是发布事件时传递的参数(以数组形式)。

官方给的例子也比较容易理解,我加了注释:


// 引入需要的方法
const { once, EventEmitter } = require('events');

async function run({
  const ee = new EventEmitter();

  process.nextTick(() => {
    // 异步发布 'myevent' 事件
    ee.emit('myevent'42);
  });

  // 监听 'myevent' 事件
  const [value] = await once(ee, 'myevent');
  // 打印 42
  console.log(value);

  const err = new Error('kaboom');
  process.nextTick(() => {
    // 异步发布 'error' 事件
    ee.emit('error', err);
  });

  try {
    await once(ee, 'myevent');
  } catch (err) {
    // 因为发布了 'error' 事件,所以要在这里的捕获reject异常
    // 打印 error happened Error: kaboom
    console.log('error happened', err);
  }
}

run();

官方例子中的代码是为了方便理解而刻意制造的,有实际生活中的例子吗?

我想到了一个。

实战

我们经常会需要将一个 Readable Stream
的内容写入到 Writable Stream
,并在写入完成(此时会发布 'finish'
事件)或写入失败时(发布'error'
事件)提供进一步的处理逻辑。

如果不知道 events.once
的存在,我们的代码只能利用 callback
回调来处理:

writableStream.on('finish',()=>{
  // 成功回调
});

writableStream.on('error',()=>{
  // 失败回调
});

而有了 events.once
, 我们便可以用上更直接且易读的 async/await
语法了:

try {
  await once(writableString, "finish");
  console.log("操作完成");
catch (e) {
  console.log("操作出错: ", e);
}

是不是舒服多了?

相关推荐


文章转载自背井,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论