JavaScript - дождитесь завершения асинхронных функций - PullRequest
0 голосов
/ 25 июня 2018

В своем расширении Chrome я проверяю каждый веб-запрос в определенном домене.Если URL соответствует определенному условию, и существует открытая вкладка, которая соответствует другому URL, я хотел бы вернуть {cancel: true}, что означает, что запрос заблокирован.

Так что мойКод работает следующим образом: если запрошенный URL-адрес соответствует моему условию, проверьте все открытые вкладки.Если одна из открытых вкладок соответствует моему (второму) состоянию, я хочу вернуть {cancel: true} из моей начальной (внешней) функции.

Проблема: return из внешнегофункция срабатывает до проверки всех вкладок (= до выполнения всех циклов forEach), поэтому всегда возвращает {cancel: false}.

[Я знаю, что есть много вопросов, связанных с этим,и одно из основных решений включает функции обратного вызова, но, в частности, в моем случае мне пока не удалось выполнить эту работу.]

Код:

function onBeforeRequestHandler (details) {
    var cancel = false;
    var url = details.url;
    // condition 1
    if (url.indexOf("condition_1") > -1){

        // check all open windows/tabs
        chrome.windows.getAll({populate:true}, function(windows){
            windows.forEach(function(single_window){
                single_window.tabs.forEach(function(tab){
                    // condition 2
                    if (tab.url.indexOf("condition_2") > -1){
                        cancel = true;
                        // this is less important - updating the tab works
                        chrome.tabs.update(tab.id, {url: url});
                    }
                });
            });
        });
        // always getting cancel = false here because it fires too quickly
        return {cancel: cancel};
    }
    else
        return {cancel: false};
}

chrome.webRequest.onBeforeRequest.addListener(onBeforeRequestHandler, {urls: ["some_domain"]}, ["blocking"]);

1 Ответ

0 голосов
/ 25 июня 2018

В настоящее время вы не можете отменить запрос на основе асинхронной функции в Google Chrome.

В Firefox, он уже поддерживает асинхронную функцию с Promise, вы можете реализовать это как следующий код.

function onBeforeRequestHandler (details) {
   var cancel = false;
   var url = details.url;
   // condition 1
   if (url.indexOf("condition_1") > -1){
       // check all open windows/tabs
       // return Promise which will be resolved after populate windows/tabs
       return browser.windows.getAll({populate:true})
           .then(function(windows) {
               windows.forEach(function(single_window) {
                   single_window.tabs.forEach(function(tab) {
                   // condition 2
                   if (tab.url.indexOf("condition_2") > -1) {
                       // this is less important - updating the tab works
                       browser.tabs.update(tab.id, {url: url});
                       return { cancel: true }
                   }
               });
           });
         })
   }
   else
       return {cancel: false};
}

история / ссылки

Согласно webRequest.onBeforeRequest в MDN.

Начиная с Firefox 52 и далее, вместо возврата BlockingResponse, слушатель может вернуть Promise, который разрешается с помощью BlockingResponse. Это позволяет слушателю обрабатывать запрос асинхронно. https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/webRequest/onBeforeRequest

Уже сообщалось о запросе функций в Chrome, как в Firefox, но этот билет НЕ был закрыт. https://bugs.chromium.org/p/chromium/issues/detail?id=625860

...