以下为ChatGPT自动生成的解答,正确与否请自行判断。

BFE.devAI解答 - JavaScript 代码题
171. create callback on message channel

实现一个 BetterChannel 类,它是在 SomeChannel 的基础上实现的,但提供了更好的可靠性:

  • BetterChannel 类可以创建两个 port,用于在它们之间进行通信。
  • 在接收端口(port2)中,当收到消息时,可以使用回调函数(reply)来处理消息,并且可以等待回复。
  • 在发送端口(port1)中,可以通过带有回调函数参数的 postMessage 方法发送消息,并且可以等待回复。

具体实现细节可以参考以下代码:

class BetterChannel {
  constructor() {
    const { port1, port2 } = new SomeChannel();
    this.sender = new ChannelSender(port1);
    this.receiver = new ChannelReceiver(port2);
  }
}

class ChannelSender {
  constructor(port) {
    this.port = port;
    this.counter = 0;
    this.callbacks = new Map();
    this.port.onmessage = (event) => {
      const { id, data } = event.data;
      if (this.callbacks.has(id)) {
        const callback = this.callbacks.get(id);
        this.callbacks.delete(id);
        callback(data);
      }
    };
  }
  postMessage(message, callback) {
    const id = ++this.counter;
    this.callbacks.set(id, callback);
    this.port.postMessage({ id, data: message });
  }
}

class ChannelReceiver {
  constructor(port) {
    this.port = port;
    this.counter = 0;
    this.callbacks = new Map();
    this.port.onmessage = (event) => {
      const { id, data } = event.data;
      const reply = (replyData) => {
        this.port.postMessage({ id, data: replyData });
      };
      this.callbacks.get(data)(data, reply);
    };
  }
  onmessage(callback) {
    const id = ++this.counter;
    this.callbacks.set(id, callback);
  }
}

BetterChannel 类里面使用了 ChannelSenderChannelReceiver 两个类来分别处理发送和接收部分的逻辑。

ChannelSender 中,每次调用 postMessage 方法时,都会生成一个唯一的 id,并将它和回调函数存到一个 Map 中。

当收到回复时,根据回复消息的 id 找到对应的回调函数,并调用它处理回复。

ChannelReceiver 中,调用 onmessage 方法时,会生成一个唯一的 id,并将它和回调函数存到一个 Map 中。

当收到消息时,根据消息的 data 查找对应的回调函数,并调用它处理消息,并传入一个 reply 函数,用于回复消息。