Как обрабатывать разные сообщения (из скрипта контента) в разных функциях фонового скрипта? - PullRequest
0 голосов
/ 23 февраля 2020

Сценарий содержимого моего расширения chrome имеет две функции прослушивания событий. Две функции отправляют разные переменные в качестве сообщения. Поэтому, если фоновый сценарий хочет различать guish между этими событиями / переменными, как мне это сделать?

Могу ли я иметь несколько функций в фоновых сценариях для прослушивания только определенного типа событий? Если да, то как мне этого добиться.

В настоящее время я посылаю идентификаторы 1 и 2 (вместе с сообщением в фоновый скрипт) из каждой функции и использую if-else для различения guish какое сообщение от какой функции. Я не думаю, что это очень элегантное решение.

Сценарий содержания:

document.getElementById("myBTN").addEventListener('click', wordSelected) {
// code
chrome.runtime.sendMessage(var1, (response) => { // id = 1
// code
});
}

window.addEventListener('change', (e)=> {
// code
chrome.runtime.sendMessage(var2, (response) => { // id = 2
// code
});
}

Сценарий фона:

chrome.runtime.onMessage.addListener(receiver);
function receiver(request, sender, sendResponse) {
if (request.id == 1) {
// code
}
else if (request.id == 2) {
// code
}

1 Ответ

0 голосов
/ 23 февраля 2020

Отправка свойства id или cmd или action или method вместе с фактическим значением является стандартным решением, концептуально лучшего нет. Вы можете использовать id: 'clicked' и id: 'changed' вместо числовых c индексов.

Что касается космеций c "решений" go, вы можете использовать Proxy API для переноса sendMessage, например, в объекте HQ ("штаб-квартира"):

async function queryHQ() {
  if (await HQ.test(1, 2, 3) === 123) {
    console.log('ok!');
  } else {
    console.log(await HQ.download());
  }
}

Чтобы это работало, сначала давайте определим HQ:

const HQ = new Proxy({}, {
  get: (_, cmd) =>
    (...args) =>
      new Promise((resolve, reject) =>
        chrome.runtime.sendMessage({cmd, args}, r =>
          !r || 'error' in r ? reject(r && r.error) : resolve(r.data)))
});

И обработаем его в фоновый скрипт использует карту команд:

const handlers = {
  test(a, b, c) {
    console.log(a, b, c);
    return 123;
  },
  async download() {
    return (await fetch(this.url)).text();
  }
};

const wrapError = error => ({error: error && error.message || `${error}`});

chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
  const {cmd, args} = msg;
  const fn = handlers[cmd];
  try {
    const res = fn.apply(sender, args);
    if (typeof res?.then === 'function') {
      res.then(data => ({data}), wrapError)
        .then(sendResponse);
      return true;
    } else if (res !== undefined) {
      sendResponse({data: res});
    }
  } catch (error) {
    sendResponse(wrapError);
  }
});

Существуют библиотеки для chrome расширений, которые реализуют аналогичный подход.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...