Требуется обратный вызов для запроса jQuery AJAX? - PullRequest
0 голосов
/ 11 октября 2018

Я довольно новичок в Javascript / jQuery, поэтому, пожалуйста, потерпите меня.Я делаю расширение Chrome, и в файле content_script.js я перебираю список ссылок и делаю ajax запросы, чтобы определить, какие из них имеют код состояния 404.Мне известно, что запросы выполняются асинхронно, и я подозреваю, что по этой причине, когда я отправляю сообщение, содержащее массив от content_script.js до popup.js, массив пуст, хотя console.log в content_script.jsпредлагает иное.

Мне любопытно, как это возможно, если console.log в content_script.js (который пришел до того, как сообщение было отправлено на popup.js) показало, что массив заполнен?Должен ли я использовать обратный вызов, чтобы решить эту проблему?Я уже попытался установить ajax, установив свойство async:false, но затем моя программа вообще не console.log и, казалось, застряла в ожидании запросов.

content_script.js

// var url = window.location.href;
var validLinks = new Array();
var array = new Array();

grabLinks();

for (var i=0;i<array.length;i++)
{
    $.ajax({
        url: array[i],
        statusCode:{
            404: function(){
                validateLink(array[i]);
            }
        }
    });
}
console.log(validLinks);//this shows me that the array IS populated
chrome.runtime.sendMessage({valid:validLinks}, function(response) {});
//but when I send the message, it is EMPTY in popup.js

function grabLinks(){
    //get all the links from the document
    let links = document.links;
    for (var i=0;i<links.length;i++)
    {
        array.push(links[i].href);
    }
}

function validateLink(link){
    //I check whether the link has been archived, and add it to an array if it has
    console.log("validating link");
    $.getJSON('http://archive.org/wayback/available?url=' + link,function(data){
        if (!$.isEmptyObject(data['archived_snapshots']))
        {
            let code = data['archived_snapshots']['closest']['status'];
            let oldUrl = data['archived_snapshots']['closest']['url'];
            console.log("pushing good url to array");
            validLinks.push(oldUrl);
        }
    });
}

popup.js

'use strict';
console.log("reached popup.js");
var searchBtn = document.getElementById("searchArchive");
var linkList = document.getElementById("fixedLinks");
searchBtn.addEventListener("click",function(){
    chrome.tabs.executeScript({file:'jquery-3.3.1.min.js'},function(){
        chrome.tabs.executeScript({
            file: 'content_script.js'
        });
    })
});

chrome.runtime.onMessage.addListener(
  function(request, sender, sendResponse) {
        let links = request.valid;
        console.log(links); //the requested array is now EMPTY
        console.log("populating link list");
        if (links.length==0)
        {
            linkList.innerHTML="no broken links were found";
        }
        for (var i=0;i<links.length;i++)
        {
            let a = document.createElement('a');
            console.log(links[a]);
            a.href = links[a];
            a.innerHTML = links[a];
            linkList.appendChild(a);
        }
  });

1 Ответ

0 голосов
/ 11 октября 2018

Вы правы, это не работает, потому что запросы ajax являются асинхронными.

Вам нужно запустить функцию chrome.runtime.sendMessage после того, как все запросы ajax завершены (как $.ajax, так и$.getJSON).Подсчитайте количество завершений и продолжайте, когда оно равно array.length.

Чтобы создать обратный вызов, который всегда выполняется после завершения $.ajax, используйте $.ajax(...).always(callbackFn)

Объекты и массивы, зарегистрированные вконсоли нельзя доверять, они показывают их текущее состояние в консоли, а не состояние, в котором они находились, когда вы их регистрировали.Чтобы это исправить, либо преобразуйте массив в строку, либо сделайте его клон.См. Этот ответ для более подробного объяснения: Странное поведение с объектами & console.log

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