Chrome 확장 : chrome.runtime.onMessage.addListener 내부의 코드가 실행되지 않습니다.

Aug 18 2020

sendMessage 메서드를 사용하여 콘텐츠 스크립트에서 popup.js로 변수를 전달하는 데 많은 문제가 있습니다.

이것은 DOM 노드의 자식 수가 포함 된 백그라운드 스크립트에 메시지를 보내는 콘텐츠 스크립트입니다.

let incomingChatsNumber = incomingChatsContainer.children().length;
chrome.runtime.sendMessage({ incomingChatsNumber: incomingChatsNumber });

그런 다음 background.js는 메시지를 듣고 동일한 변수를 가진 메시지 자체를 popup.js에 보냅니다.

chrome.runtime.onMessage.addListener(function (message, sender, sendResponse) {
  let incomingChatsNumber = message.incomingChatsNumber;
  chrome.runtime.sendMessage({ incomingChatsNumber: incomingChatsNumber });
});

popup.js에는 "incomingChatsNumber"가 0보다 큰 경우 일부 코드를 트리거하는 버튼이 있습니다 (dom 컨테이너에 자식이 있음).

  $("#js-toggleSorting").on("click", function () { chrome.runtime.onMessage.addListener(function (message) { let incomingChatsNumber = message.incomingChatsNumber; if (incomingChatsNumber <= 0) { $(".message").html("<p>No Chats To Sort, You Joker</p>");
      } else {
        $(".message").html("<p>Sorting Chats</p>"); //This code never gets executed if ($("#js-toggleSorting").attr("data-click-state") == 1) {
          $("#js-toggleSorting").attr("data-click-state", 0); $("#js-toggleSorting").html("SORT INCOMING CHATS");
          sortFunction(false);
        } else {
          $("#js-toggleSorting").attr("data-click-state", 1); $("#js-toggleSorting").html("STOP SORTING INCOMING CHATS");
          sortFunction(true);
        }
        save_button_state();
      }
    });
  });

나에게 이상한 점은 popup.js가 올바른 값을 얻는다는 것입니다. console.log도 할 수 있지만 조건부 코드를 추가하자마자 조건이 괜찮더라도 코드가 실행되지 않습니다.

최신 정보:

ehab에서 제안한 수정을 수행 한 후 chrome.runtime.onMessage.addListener의 비동기 특성으로 인해 변수가 항상 "정의되지 않음"이라는 것을 깨달았습니다.

콘텐츠 스크립트 :

  let incomingChatsNumber = incomingChatsContainer.children().length;
  chrome.runtime.sendMessage({ incomingChatsNumber: incomingChatsNumber });

Background.js :

chrome.runtime.onMessage.addListener(function (message) {
  let incomingChatsNumber = message.incomingChatsNumber;
  chrome.runtime.sendMessage({ incomingChatsNumber: incomingChatsNumber });
});

Popup.js (incomingChatsNumber 변수의 값을 사용해야하는 곳입니다) :

  let latestIncomingChatsNumber;

  chrome.runtime.onMessage.addListener(function (message) {
    let incomingChatsNumber = message.incomingChatsNumber;
    latestIncomingChatsNumber = incomingChatsNumber;
    //This Works
    console.log(latestIncomingChatsNumber);
  });
  //This will give me an undefined value
  console.log(latestIncomingChatsNumber);

내 문제는 chrome. * API가 비동기 적이므로 chrome.runtime ...과 console.log (...)가 동시에 실행되므로 오류가 발생한다는 사실과 관련이 있습니다. 그렇다면 클릭 이벤트 내에서 latestIncomingChatsNumber 변수를 사용하는 방법은 무엇입니까? 먼저 "latestIncomingChatsNumber"를 chrome.runtime.onMessage.addListener 내부의 로컬 저장소에 저장해야합니까?

답변

1 ehab Aug 18 2020 at 21:41

다른 이벤트 핸들러 내부에 이벤트 리스너를 두어서는 안됩니다. 이것은 당신이해야한다고 생각하는 일을하더라도 극도로 나쁜 습관입니다. 이것은 당신을 위해 메모리 누수를 유발하고 코드를 읽기 어렵게 만들고 의미 론적으로 만듭니다. 올바르지 않습니다.

코드를 살펴보면 문제는 클릭 evet에 추가 된 이전 이벤트 리스너로 인해 메시지 처리기가 여러 번 호출된다는 것입니다.

 let latestIncomingChatsNumber
 chrome.runtime.onMessage.addListener(function (message) {
      let incomingChatsNumber = message.incomingChatsNumber;
      // save this into the application state, i will use a parent scope variable you could use something else 
       latestIncomingChatsNumber = incomingChatsNumber
    });
    
 $("#js-toggleSorting").on("click", function () { if (latestIncomingChatsNumber <= 0) { $(".message").html("<p>No Chats To Sort, You Joker</p>");
      } else {
        $(".message").html("<p>Sorting Chats</p>"); //This code never gets executed if ($("#js-toggleSorting").attr("data-click-state") == 1) {
          $("#js-toggleSorting").attr("data-click-state", 0); $("#js-toggleSorting").html("SORT INCOMING CHATS");
          sortFunction(false);
        } else {
          $("#js-toggleSorting").attr("data-click-state", 1); $("#js-toggleSorting").html("STOP SORTING INCOMING CHATS");
          sortFunction(true);
        }
        save_button_state(); // i believe this function saves the attributes to the dom elements
      }
  });

경우에 save_button_state좋은 일을 내가 공유 코드가 작동합니다