Node.js EventEmitter裡註冊接收事件一般使用 .on(‘event name’, handler) 的方式,但有一個api是 .once,也就是註冊後觸發listener會自動remove,可參考
https://nodejs.org/docs/latest-v12.x/api/events.html#events_emitter_once_eventname_listener
.once 在一般情境較少用到,原因是處理接收事件常常是跟著發送事件的物件生命週期(例如stream的’data’事件,.once只做一次性的handle,能使用到的情境比較像是需要接收到狀態變更,系統落入A狀態要等待切換到B狀態,因此在A狀態時註冊一個接收切換到B狀態的listener,一旦切換到B狀態就remove listener,等待下一次落入A狀態時再註冊
在Node.js doc介紹stream的地方有個不錯的範例 https://nodejs.org/docs/latest-v12.x/api/stream.html#stream_stream 節錄於下
// Write the data to the supplied writable stream one million times.
// Be attentive to back-pressure.
function writeOneMillionTimes(writer, data, encoding, callback) {
let i = 1000000;
write();
function write() {
let ok = true;
do {
i--;
if (i === 0) {
// Last time!
writer.write(data, encoding, callback);
} else {
// See if we should continue, or wait.
// Don't pass the callback, because we're not done yet.
ok = writer.write(data, encoding);
}
} while (i > 0 && ok);
if (i > 0) {
// Had to stop early!
// Write some more once it drains.
writer.once('drain', write);
}
}
}
可以注意 當writer.write 失敗時,就休息等待’drain’ event,再繼續write,也就是如上描述的 – 等待新的狀態變更。
Pingback: Nodejs Events 整理 | C++ Essay