Предотвратить несколько казней одного и того же слушателя - PullRequest
0 голосов
/ 04 мая 2020

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

Проблема: функция, вызываемая в слушателе, является асин c, и до завершения первого вызова происходит несколько последовательных модификаций, которые генерируют нежелательные результаты;

Здесь это упрощенный пример, иллюстрирующий ситуацию.

var obj = new MyClass();

async function modifyObj( windowId, tabId, changeInfo ){
    // modify object (X)
    var window = await new Promise( (resolve,reject) => {
        chrome.windows.get(windowId, {populate: true}, (w) => resolve(w));
    });
   // modify object (Y)
}

chrome.tabs.onUpdate.addListener( (tabId, changeInfo, tab) => {
    modifyObj(tab.windowId, tab.id, changeInfo);
});

Допустим, 3 вкладки получили обновления по очереди (например, когда вы одновременно открываете 3 вкладки из закладок)

Выполнения запускают что-то как следует

  1. Обновление вкладки 1
    • анонимный прослушиватель
    • modifyObject до await
  2. Обновление вкладки 2
    • анонимный слушатель
    • modifyObject до await
  3. Обновление вкладки 3
    • анонимный слушатель
    • modifyObject до await
  4. await вызовы разрешаются в некотором порядке, а затем выполняется остальная часть modifyObject

До await код, отмеченный modify object (X), запускается несколько раз, прежде чем будет выполнено первое выполнение modifyObject. По разным причинам в исходном коде этого не может быть. Код на modify object (Y) строго зависит от изменений, сделанных в modify object (X).

Что я хочу:

  1. Обновление вкладки 1
    • анонимный слушатель
    • modifyObject до await
    • выполнение остальных функций
  2. Обновление вкладки 2
    • анонимный прослушиватель
    • modifyObject до await
    • выполнение остальных функций
  3. Обновление вкладки 3
    • анонимный прослушиватель
    • modifyObject до await
    • выполнение остальных функций

Но, конечно, мы не можем контролировать, когда chrome запустит слушатели.

Каковы эффективные и простые способы сделать это?

1 Ответ

1 голос
/ 04 мая 2020

Вы можете иметь каждый вызов modifyObj цепочки от предыдущего вызова функции, так что одновременно выполняется не более одного вызова:

const obj = new MyClass();
let modifyProm = Promise.resolve();
async function modifyObj( windowId, tabId, changeInfo ){
    // modify object (X)
    var window = await new Promise( (resolve,reject) => {
        chrome.windows.get(windowId, {populate: true}, (w) => resolve(w));
    });
   // modify object (Y)
}

chrome.tabs.onUpdate.addListener( (tabId, changeInfo, tab) => {
    modifyProm = modifyProm.then(() => modifyObj(tab.windowId, tab.id, changeInfo));
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...