Обещайте дождаться Chrome.runtime.sendMessage - PullRequest
0 голосов
/ 30 августа 2018

Я всегда видел, как Promise работает с setTimeout, но я пытаюсь сделать это на основе того, что chrome.runtime.sendMessage вернет в Promise.

У меня есть скрипт содержимого, который выполняет эту функцию после его завершения.

chrome.runtime.sendMessage({complete: true});

У меня есть фоновый скрипт, который перебирает каждый элемент в массиве и использует одно из его значений для открытия URL-адреса с помощью chrome.tabs.update.

То, что я пытаюсь сделать, это заставить асинхронную функцию ждать сообщения, которое отправляет скрипт содержимого, и продолжить следующую итерацию только после получения сообщения, хотя я не знаю, как это реализовать, поскольку я Вы видели только примеры с setTimeout.

Так и должно быть

  1. Открыть первый элемент в массиве и остановить
  2. Выполните скрипт содержимого на этой странице и выполните sendMessage в конце.
  3. Теперь фоновый скрипт должен ожидать получения sendMessage, прежде чем перейти к следующему элементу.
  4. Как только sendMessage было получено с onMessage, оно должно перейти к следующему пункту и повторить с шага 2

Это фоновый скрипт.

    chrome.storage.local.get('userItems', function(result) {
    console.log(result.userItems);

    function delay() {
      // I suppose I should do something with onMessage in the delay function
      return new Promise(resolve => setTimeout(resolve, 500));
    }

    async function delayedLog(item) {
      await delay();

      console.log(item);
      var url = "http://www.example.com/" + item.Category;

      chrome.tabs.update({
        url: url
      });
    }

    async function processArray(array) {
      for (const item of array) {
        await delayedLog(item);
      }
    }

    processArray(result.userItems);

    });

1 Ответ

0 голосов
/ 30 августа 2018

Проще попросить контент-скрипт выполнить свою работу и ответить, когда он закончится.
Чтобы заставить sendMessage работать с обещаниями, вы можете обернуть его:

/**
 * Promise wrapper for chrome.tabs.sendMessage
 * @param tabId
 * @param item
 * @returns {Promise<any>}
 */
function sendMessagePromise(tabId, item) {
    return new Promise((resolve, reject) => {
        chrome.tabs.sendMessage(tabId, {item}, response => {
            if(response.complete) {
                resolve();
            } else {
                reject('Something wrong');
            }
        });
    });
}

Контент-скрипт должен иметь что-то вроде этого:

// waiting for tasks from background
chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
    const item = msg.item;

    // ..process your "item"

    sendResponse({complete: true}); // telling that CS has finished its job

    // 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).
    return true;
});
...