Можно ли выполнить gm_xmlhttprequest асинхронно?

Я попытался поместить gm_xmlhttprequest в цикл while, но код выполняется синхронно. Можно ли заставить его выполняться асинхронно, по одному?


person frosty    schedule 24.08.2018    source источник
comment
but the code executes synchronously — не устанавливайте synchronous:true — поведение по умолчанию асинхронно, поэтому оно синхронно только потому, что вы установили synchronous:true в аргументе details   -  person Jaromanda X    schedule 24.08.2018
comment
о, подождите.... asynchronously, one at a time ... эм... вы перепутали слова asynchronous и synchronous - если запросы делать асинхронно, то все они будут выполняться сразу (не совсем так, но ждать нечего) - то, что вы хотите (но не делайте этого) для того, чтобы запросы выполнялись синхронно, чтобы вы могли выполнять их по одному... но не делайте этого... применяйте асинхронность - вы все равно можете выполнять один одновременно асинхронно   -  person Jaromanda X    schedule 24.08.2018
comment
@JaromandaX Э-э ... Я думаю, у вас это наоборот. Синхронность существует или происходит одновременно. Асинхронно, по одному. Просто чтобы подтвердить, я погуглил, и это то, что сказал гугл.   -  person frosty    schedule 24.08.2018
comment
добавьте synchronous:true к объекту сведений, который вы передаете gm_xmlhttprequest, и ваш код будет вести себя так, как вы хотите - ясно, что создатели Greasemonkey подшучивают над вами, когда установка synchronous:true делает запрос асинхронным - но вы знаете программистов, всегда хотелось бы посмеяться последним - я уверен, что MDN также намеренно вводит вас в заблуждение< /а>   -  person Jaromanda X    schedule 24.08.2018
comment
в программировании думайте о синхронном как о последовательном - т.е. код выполняется последовательно в том порядке, в котором он написан, каждый оператор ждет завершения предыдущего оператора перед выполнением... тогда как в асинхронном коде части кода могут выполняться позже, когда становится доступным какое-то внешнее событие или результат, поэтому он не является последовательным (это то, что касается обратных вызовов и любых других асинхронных шаблонов кода, которые вы видите просто прославленные обратные вызовы)   -  person Jaromanda X    schedule 24.08.2018
comment
@JaromandaX Я очень смущен. Вы говорите, что значение слов «синхронный» и «асинхронный» в программировании противоположно тому, что сами слова означают при использовании вне программирования?   -  person frosty    schedule 24.08.2018
comment
нет, я говорю, что они означают одно и то же, это ваша интерпретация неверна ... на самом деле, это, вероятно, несправедливо ... значения в javascript имеют разный контекст - поверьте мне - вы хотите синхронно запросы (хотя на самом деле вы этого не хотите из-за влияния на пользовательский интерфейс) - если, как это является одним из основных условий для вопросов по SO, вы включили свой код (или часть, с которой имеете дело), ​​тогда Я мог бы показать вам, как именно делать то, что вы хотите, аккуратно и асинхронно.   -  person Jaromanda X    schedule 24.08.2018
comment
@JaromandaX Я редактировал части своих кодов выше. По сути, я хочу добавить ссылки в длинный список ссылок, если они совпадают. Но поскольку код запускается одновременно, я добавляю только последнюю ссылку.   -  person frosty    schedule 24.08.2018
comment
@JaromandaX Нет, это только часть кода. Переменная link имеет разные ссылки каждый раз, когда она проходит через цикл while.   -  person frosty    schedule 24.08.2018
comment
достаточно справедливо, ответ добавлен   -  person Jaromanda X    schedule 24.08.2018


Ответы (1)


самое простое изменение вашего кода будет следующим

function doXHR(counter) {
    if (counter < count) {
        var GoToURL = link;
        GM_xmlhttpRequest({
            method: "GET",
            url: GoToURL,
            onload: function(response) {
                if (response.finalUrl.match(/true$/)) { 
                    longList = longList + link; 
                }
                doHXR(counter+1);
            }
        });
    }
}
doXHR(0);

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

Если вам нужно запустить этот код, то, когда все запросы будут выполнены, продолжайте делать что-то еще.

function doAllXHR(count, callback) {

    function doXHR(counter) {
        if (counter < count) {
            var GoToURL = link;
            GM_xmlhttpRequest({
                method: "GET",
                url: GoToURL,
                onload: function(response) {
                    if (response.finalUrl.match(/true$/)) { 
                        longList = longList + link; 
                    }
                    doHXR(counter+1);
                }
            });
        } else {
            callback('done');
        }
    }
    doXHR(0);
}

doAllXHR(20, function(result) {
    console.log(result);
    // and continue with whatever it is you do
});
person Jaromanda X    schedule 24.08.2018
comment
Я попробовал этот код, но он обрабатывает только первые несколько ссылок, а затем прекращает обработку остальных ссылок. - person frosty; 24.08.2018
comment
Точнее, счетчик идет от 0 до 1, а затем останавливается. - person frosty; 24.08.2018
comment
и обработчик onerror - вы, вероятно, получаете сообщение об ошибке - или, может быть, response.finalUrl это undefined - в консоли браузера (ctrl+shift+j) может быть сообщение об ошибке для вас - person Jaromanda X; 24.08.2018
comment
В консоли нет ошибки. Но когда я попытался предупредить счетчик, он просто предупреждает 0, затем 1, а затем просто останавливается. - person frosty; 24.08.2018
comment
Подождите... на самом деле в консоли есть некоторые ошибки. - person frosty; 24.08.2018
comment
вы видели мою опечатку? doHXR(counter+1); это неправильно - должно быть doXHR(counter+1); - person Jaromanda X; 24.08.2018
comment
Да, я исправил это некоторое время назад. Прямо сейчас я просто получаю несколько ошибок в консоли. Первый - Uncaught TypeError: невозможно прочитать свойство "длина" нулевого значения. - person frosty; 24.08.2018
comment
ну, это связано с кодом, который вы не публиковали — потому что вы никогда не пытаетесь получить доступ к свойству .length в любом опубликованном вами коде — возможно, поскольку вы на самом деле не публиковали много о код, который у вас есть, вы не правильно реализовали мое предложение - person Jaromanda X; 24.08.2018
comment
Не бери в голову. Я вызывал функцию внутри оператора if, и она прошла с первой и второй попытки, но не с третьей, поэтому функция перестала вызываться на третьем цикле. Я починил это. Спасибо, ваша функция работает отлично. - person frosty; 24.08.2018
comment
Ждать. Этот код. Я попытался добавить ссылки на файлы cookie внутри функции загрузки. Но это только добавляет последнюю ссылку снова и снова. Я думаю, что этот код все еще работает в то же время... - person frosty; 24.08.2018
comment
невозможно... doXHR(1) не будет выполняться до тех пор, пока не произойдет событие загрузки (т.е. завершено) doXHR(0) - person Jaromanda X; 24.08.2018
comment
Хорошо. Я отредактировал код. CheckIfAlreadyDidHits выше и ниже обе предупреждает каждый раз о разных ссылках, но та, что находится внутри функции onload, каждый раз оповещает одну и ту же ссылку, и она выполняется только ПОСЛЕ предупреждения checkIfAlreadyDidHits как выше, так и ниже. - person frosty; 24.08.2018
comment
Извините, вы можете не принимать или что-то еще, но я не собираюсь переписывать ответ, чтобы он соответствовал вашему новому неформатированному и невозможному для чтения коду - пожалуйста, отмените этот ответ, и я удалю его. - person Jaromanda X; 24.08.2018
comment
Вот почему в первый раз я использовал меньше кода, чтобы вам было легче его читать. Знаешь что? Я напишу более короткую примерную версию, а затем дам вам взглянуть на нее. Все хорошо? - person frosty; 24.08.2018
comment
Не бери в голову. Я его более или менее отладил, и теперь он работает. - person frosty; 24.08.2018