DRYな備忘録

Don't Repeat Yourself.

sendResponseが動いてないように見える現象に半年に1回ひっかかってる気がする

background.js

chrome.runtime.onMessage.addEventListener((req, sender, sendRes) => {
    setTimeout(() => {
      // ここまで来てるのに
      sendRes("元気でーす");
    }, 100);
});

contents_script.js

chrome.runtime.sendMessage(null, {msg:"元気ですか?"}, (res) => {
    window.alert("返事:" + res); // ここに来ない
});

原因

stackoverflow.com

chrome.runtime - Google Chrome

sendResponse
Function to call (at most once) when you have a response. The argument should be any JSON-ifiable object. If you have more than one onMessage listener in the same document, then only one may send a response. This function becomes invalid when the event listener returns, unless you return true from the event listener to indicate you wish to send a response asynchronously (this will keep the message channel open to the other end until sendResponse is called).

レスポンスを返したいときはこのコールバック関数を使うこと。引数にはJSONにできるオブジェクトを渡す。onMessageに複数のリスナーつけても、ひとつしか呼ばれないよ。このコールバック関数は、イベントリスナー関数がreturnすると、使えなくなるよ。もしイベントリスナー関数がreturnした後もコールバック関数を使ってレスポンスを返したければ、イベントリスナー関数で true を返して、非同期でこのコールバック関数を使うことを明示してくれ(sendResponseが呼ばれるまでチャンネルを閉じないでおくので)。

そういやそうだったわ。

chrome.runtime.onMessage.addEventListener((req, sender, sendRes) => {
    setTimeout(() => {
      sendRes("元気でーす");
    }, 100);
+    return true;
});

DRYな備忘録として