Загрузка упорядоченного (синхронного) содержимого HTML с помощью асинхронного JavaScript - PullRequest
0 голосов
/ 17 февраля 2019

У меня есть отдельные HTML-файлы, содержащие небольшие фрагменты контента, которые загружаются с использованием AJAX и .get ().Я хочу иметь возможность отображать заказанный контент без , используя async: false в моем вызове AJAX, так как этот метод устарел.По мере роста сайта я также обеспокоен тем, что синхронный JavaScript будет негативно влиять на производительность.

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

В настоящее время я выполняю загрузку и отображение «упорядоченного содержимого», сортируя массив и используя async: false в вызове AJAX.

function loadOrderedContent(divID, directory) {
/* populate_index.php JSON query must exist in directory */

    /* empty any previous div content */
    $('#' + divID).empty();

    $.get(directory + 'populate_index.php', function(logindex) {

        /* parse populate_index.php and determine length */
        var decoded_logindex = JSON.parse(logindex);
        var size = decoded_logindex.length;

        /* remove ".." and "." from end of decoded_logindex */
        decoded_logindex.splice(size - 2, 2)
        size = decoded_logindex.length;

        /* NOTE: This is where I manipulate array */
        // ~~array manipulation function(s)~~

        /* populate div with ordered content */
        for (i = 0; i < size; i++) {
            if (decoded_logindex[i] != 'populate_index.php') {
                $.ajax({
                    url: directory + decoded_logindex[i],
                    async: false, // <<== I don't want this anymore
                    success: function(data) {
                        /* append HTML content to desired div */
                        $('#' + divID).append(data);
                    },
                    error: function() {
                        alert("Synchronous AJAX request failed");
                    }
                });
            }
        }
    });
}

Это дает мне желаемые результаты.Однако, если я использую асинхронное решение (чтобы избежать устаревания), div случайно загружается при загрузке содержимого HTML.

1 Ответ

0 голосов
/ 17 февраля 2019

Вы можете использовать Promise.all, чтобы дождаться возвращения всех ответов, и как только они это сделают, у вас будет массив в порядке оригинала decoded_logindex, и вы можете добавить все сразу:

const proms = decoded_logindex
  .filter(str => str !== 'populate_index.php')
  .map(str => $.ajax(directory + str));
Promise.all(proms)
  .then((dataArr) => {
    const $elm = $('#' + divID);
    dataArr.forEach((data) => {
      $elm.append(data);
    });
  })
  .catch((err) => {
    alert("Request failed");
  });

В качестве альтернативы, если вы хотите, чтобы невыполненный запрос не приводил к сбою всего процесса, вы можете вместо этого добавить строку ошибки, catch используя $.ajax вместо catch используя Promise.all:

const proms = decoded_logindex
  .filter(str => str !== 'populate_index.php')
  .map(str => (
    $.ajax(directory + str)
    .catch(() => '<span>Error fetching ' + str + '</span>')
  ));
Promise.all(proms)
  .then((dataArr) => {
    const $elm = $('#' + divID);
    dataArr.forEach((data) => {
      $elm.append(data);
    });
  })
...