在 chrome/firefox 扩展 API 中,如何在不发送新消息的情况下从端口获得链接响应?

In chrome/firefox extension API, how do I get a chained response from port without sending a new message?

对于一次性消息,发送方发送消息,接收方通过回调接收响应。

// Sender
chrome.runtime.sendMessage({greeting: "hello"}, function(response) {
  console.log(response.farewell);
});

// Receiver
chrome.runtime.onMessage.addListener(
  function(request, sender, sendResponse) {
      if (request.greeting == "hello")
          sendResponse({farewell: "goodbye"});
  }
);

对于端口通信,API 文档和示例是这样的,发送方发送消息,接收方发送新消息但不作为响应。

例如

// Sender
port?.postMessage({greeting: "hello"});

port.onMessage.addListener(function(msg) {
  if (msg.farewell)
      console.log("Farewell is", msg.farewell)
});
// Receiver
port.onMessage.addListener(function(msg) {
  if (msg.greeting == "hello")
    port.postMessage({farewell: "goodbye"});
});

是否可以使用可以 return 响应作为回调或承诺的端口通信来模拟一次性消息通信,以便我可以链接逻辑。链接响应,尤其是使用 browser-polyfil 进行异步等待,使代码逻辑流程更加自然。

端口通讯无回调响应。 但是,您可以使用等待特定消息的异步包装器进行模拟。 这不仅会捕获接收者的响应,还会捕获所有匹配的 msg.subject。 但是,有了这个,您仍然可以在一个函数中完成所有逻辑,而不是在侦听器中零碎地完成。

async function waitForResponse(port, subject) {
  return new Promise((resolve) => {
    const callback = (msg) => {
      if (msg.subject === subject) {
        port.onMessage.removeListener(callback);
        resolve(msg);
      }
    };
    port.onMessage.addListener(callback);
  });
}