Загрузка упорядоченного (синхронного) содержимого HTML с помощью асинхронного JavaScript

У меня есть отдельные файлы 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.

Будет ли нормально, если все будет добавлено сразу, как только все запросы будут выполнены?

CertainPerformance 17.02.2019 01:21

@CertainPerformance Да, если все было в том порядке, который я указал в массиве.

Vincent T. Mossman 17.02.2019 01:24
Как конвертировать HTML в PDF с помощью jsPDF
Как конвертировать HTML в PDF с помощью jsPDF
В этой статье мы рассмотрим, как конвертировать HTML в PDF с помощью jsPDF. Здесь мы узнаем, как конвертировать HTML в PDF с помощью javascript.
1
2
38
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете использовать 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);
    });
  })

Другие вопросы по теме