Rx.js,Chrome Messaging API

Tom*_*Tom 5 google-chrome-extension rxjs

扩展的另一部分使用此代码发送消息后

chrome.runtime.sendMessage({greeting: "hello"});
Run Code Online (Sandbox Code Playgroud)

任何可以使用此消息传递API的Rx.js专家

chrome.runtime.onMessage.addListener(
  function(request, sender, sendResponse) {
    console.log(sender.tab ?
                "from a content script:" + sender.tab.url :
                "from the extension");
    if (request.greeting == "hello")
      sendResponse({farewell: "goodbye"});
});
Run Code Online (Sandbox Code Playgroud)

并将其包装在发出新消息并允许sendResponse的Observable中?

简单地将传入消息作为Observable发出非常容易。

const MessagingObservable = Rx.Observable.create(observer => {      
  chrome.runtime.onMessage.addListener(listener);
  function listener(request, sender, sendResponse) {
    observer.next(request); 
  }
  return () => {
    chrome.runtime.onMessage.removeListener(listener);
  };
});
Run Code Online (Sandbox Code Playgroud)

但是如何绑定sendResponse回调?

car*_*ant 5

您可以使用内置fromEventPattern函数来创建可观察对象,如下所示:

const messages = Rx.Observable.fromEventPattern(
  handler => chrome.runtime.onMessage.addListener(handler),
  handler => chrome.runtime.onMessage.removeListener(handler),
  (request, sender, sendResponse) => ({ request, sender, sendResponse })
);
Run Code Online (Sandbox Code Playgroud)

请注意,该呼叫fromEventPattern包括结果选择,使得由观察到的发射值包含requestsender,以及sendResponse,你会使用这样的:

messages.subscribe(({ request, sender, sendResponse }) => {
  console.log(request);
  sendResponse(/* ... whatever ... */);
});
Run Code Online (Sandbox Code Playgroud)

为了支持sendResponse异步调用,侦听器需要能够返回true。可以通过包装来完成handler,如下所示:

const messages = Rx.Observable.fromEventPattern(
  handler => {
    const wrapper = (request, sender, sendResponse) => {
      const event = { async: false, request, sender, sendResponse };
      handler(event);
      return event.async;
    };
    chrome.runtime.onMessage.addListener(wrapper);
    return wrapper;
  },
  (handler, wrapper) => chrome.runtime.onMessage.removeListener(wrapper)
);
Run Code Online (Sandbox Code Playgroud)

并且您将像这样使用它:

messages.subscribe(event => {
  console.log(event.request);
  event.async = true;
  setTimeout(() => event.sendResponse(/* ... whatever ... */), 1000);
});
Run Code Online (Sandbox Code Playgroud)