我正在从两个其他api创建动态菜单。菜单将通过父/子关系创建。这意味着父ajax响应的id将传递给子ajax以获取子记录。

问题是,当我对我的孩子ajax调用使用async false时,我的网站变慢,并且删除它时,菜单无法呈现。对此有所帮助。

我的代码家长致电

var url;
url = "/_api/lists/getbytitle('GlobalTopNavMenu')/items?$select=Id,Title,Image,hasSubMenu,Link&$filter=Location eq 'GlobalNavigation'";
html = "<ul class='nav navbar-nav nav-topmrgn'>";
$.ajax({
  url: url,
  method: "GET",
  headers: {
    "Accept": "application/json; odata=verbose"
  },
  success: function(data) {
    $.each(data.d.results, function(i, item) {
      if (item.hasSubMenu == "Yes") {
        html += "<li class='dropdown yamm-fw borderLeftY'><a href='#' title='' class='dropdown-toggle' data-toggle='dropdown' role='button' aria-haspopup='true' aria-expanded='false'>" + Res[item.Title] + "<b class='caret'></b></a>";
        html += getSubMenu(item.Id) + "</dl>";
        html += "<dl class=''><dd class='picHolder'><img alt='' src='/PublishingImages/" + item.Image + "'/></dd></dl></div></div></li></ul></li>";
      } else
        html += "<li class='yamm-fw borderLeftY'><a href='" + item.Link + "' title='' class='dropdown-toggle' role='link' aria-haspopup='true' aria-expanded='false'>" + Res[item.Title] + "</a></li>";
    })
    html += "</ul>";
    $("#navbar").empty();
    $("#navbar").append(html);
  }
});


儿童电话

function getSubMenu(id) {
  var url = "/_api/lists/getbytitle('GlobalSubNavMenu')/items?$select=Id,Title,Link,ParentMenu/Id,root&$filter=ParentMenu/Id eq " + id + "&$expand=ParentMenu/Id";
  var html = "";
  $.ajax({
    url: url,
    method: "GET",
    async: false,
    headers: {
      "Accept": "application/json; odata=verbose"
    },
    success: function(data) {
      if (data.d.results.length < 6)
        html += "<ul class='dropdown-menu width500 spaceLeft'>"; //
      else
        html += "<ul class='dropdown-menu width800 spaceLeft'>";
      html += "<li><div class='yamm-content'><div class='row'><dl class='col-sm-3 mega-menu colborderRight'>";
      $.each(data.d.results, function(i, item) {
        if (i !== 0 && i % 6 == 0)
          html += "</dl><dl class='col-sm-3 mega-menu colborderRight'><dd class=''><a href=/" + (item.root ? "" : lang) + item.Link + ">" + Res[item.Title] + "</a></dd>";
        else
          html += "<dd class=''><a href=/" + (item.root ? "" : lang) + item.Link + ">" + Res[item.Title] + "</a></dd>";
      });
    }
  });
  return html;
}


如果我从子函数中删除async false,则菜单将不会呈现。那我该怎么做。

最佳答案

对于async: falsegetSubMenu()是异步的,因此,


getSubMenu()必须返回promise(良好做法)或接受回调(不良做法),
依赖于从getSubMenu()获得的数据的代码必须进行相应的分解。


这不是处理异步派生数据的最简单介绍,尤其是因为getSubMenu()是在循环内调用的。

您需要了解以下内容:


jQuery.ajax()返回一个承诺,使您可以链接.then()。解决此问题时,您将受益于.then()的“成功:”回调的巨大力量。
Array#map()将数组映射到您喜欢的新数组。在这里Array#map()在创建由getSubMenu()返回的promise数组时特别有用。
jQuery.when()聚合多个promise,并返回一个promise。


这是一个框架化的模式,可以解决您的问题:

$.ajax({...})
.then(function(data) { // then() not success: ...
    var promises = data.d.results.map(function(item) {
        if (item.hasSubMenu == 'Yes') {
            return getSubMenu(item.Id).then(function(subMenu) {
                return '...'; // build and return an HTML string here, including the `subMenu` created by `getSubMenu()`.
            });
        } else {
            return '...'; // return hard-coded HTML.
        }
    });
    // At this point, promises is an array comprising some unknown mix of jQuery promises and HTML strings.
    return jQuery.when.apply(null, promises).then(function(/* each argument is an HTML fragment, as generated above */) {
        var html = Array.prototype.join.call(arguments, ''); // slightly awkward syntax for joining `arguments` into a single string.
        $("#navbar").html('...' + html + '...');
    });
});

function getSubMenu(id) {
    var url = "...";
    return $.ajax({...}}) // getSubMenu() must return a promise.
    .then(function(data) { // then() not success: ...
        var html = "..."; // initial HTML fragment
        var arr = data.d.results.map(function(item) {
            return '...'; // build and return HTML based on item.
        });
        // At this point, `arr` is an array of HTML fragments, that can be concatenated with Array#join().
        return html + '...' +  arr.join('') + '...'; // by using .then(), the promise returned by getSubMenu() will deliver whatever is returned here.
    });
}


在全 :

var url = "/_api/lists/getbytitle('GlobalTopNavMenu')/items?$select=Id,Title,Image,hasSubMenu,Link&$filter=Location eq 'GlobalNavigation'";
$.ajax({
    url: url,
    method: "GET",
    headers: {
        "Accept": "application/json; odata=verbose"
    }
}).then(function(data) {
    var promises = data.d.results.map(function(item) {
        if (item.hasSubMenu == 'Yes') {
            return getSubMenu(item.Id).then(function(subMenu) {
                return '<li class="dropdown yamm-fw borderLeftY"><a href="#" title="" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">' + Res[item.Title] + '<b class="caret"></b></a>' + subMenu + '<dl class=""><dd class="picHolder"><img alt="" src="/PublishingImages/' + item.Image + '"/></dd></dl></div></div></li></ul></li>';
            });
        } else {
            return '<li class="yamm-fw borderLeftY"><a href=#"' + item.Link + '" title="" class="dropdown-toggle" role="link" aria-haspopup="true" aria-expanded="false">' + Res[item.Title] + '</a></li>';
        }
    });
    return $.when.apply(null, promises).then(function() {
        $("#navbar").html('<ul class="nav navbar-nav nav-topmrgn">' + Array.prototype.join.call(arguments, '') + '</ul>');
    });
});

function getSubMenu(id) {
    var url = "/_api/lists/getbytitle('GlobalSubNavMenu')/items?$select=Id,Title,Link,ParentMenu/Id,root&$filter=ParentMenu/Id eq " + id + "&$expand=ParentMenu/Id";
    return $.ajax({
        url: url,
        method: 'GET',
        headers: {
            'Accept': 'application/json; odata=verbose'
        }
    }).then(function(data) {
        var html = (data.d.results.length < 6) ? '<ul class="dropdown-menu width500 spaceLeft">' : '<ul class="dropdown-menu width800 spaceLeft">';
        html += '<li><div class="yamm-content"><div class="row">';
        var arr = data.d.results.map(function(item) {
            return '<dd class=""><a href=/' + (item.root ? '' : lang) + item.Link + '>' + Res[item.Title] + '</a></dd>';
        });
        return html + '<dl class="col-sm-3 mega-menu colborderRight">' +  arr.join('') + '</dl>';
    });
}

10-05 23:14