加载有序(同步)HTML 异步内容 JavaScript

Loading Ordered (Synchronous) HTML Content with Asynchronous JavaScript

我有单独的 HTML 文件,其中包含使用 AJAX 和 .get() 加载的少量内容。我希望能够在我的 AJAX 调用中使用 async: false 显示有序内容 而无需 ,因为此方法已弃用。随着站点的增长,我也担心同步 JavaScript 会损害性能。

我可以访问一个包含完整文件名列表的数组。通常,这些应该根据文件名以字母数字顺序显示;但是,在某些情况下我确实需要操纵顺序。我希望通过简单地操作数组来完成这个。

目前,我通过对数组进行排序并在 AJAX 调用中使用 async: false 来完成加载和显示此 "ordered content"。

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 内容加载时随意填充。

您可以使用 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");
  });

或者,如果您希望失败的请求不会导致整个过程失败,您可以附加一个错误字符串,方法是 catching $.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);
    });
  })