这个Promise.all解决方案有什么问题

时间:2017-11-24 22:38:25

标签: javascript drop-down-menu promise es6-promise

我需要遍历一系列项目并检查每个项目的类型是否与所需类型匹配。完成所有检查后,将符合要求的检查添加到下拉选择框中。在一个满足要求的2个项目的数组中,此代码检查只是将第一个项目添加到下拉列表中,它有什么问题?

var promises = [];
var html = "";

for (var i = 0; i < items.length; i++) {
  var promise = new Promise(function(resolve, reject){
    $.ajax({
      url: "url" + items[i], 
      dataType: "json",
      success: function (data) {
        console.log(data); 
        console.log(data.type); // "mytype"
        console.log(typeof data.type); // string
        if(data.type == "mytype") {
          html += "<option value='" + data.id + "'>" + items[i] + "</option>";
          resolve();
        }
      }
    });
  promises.push(promise); 
  });
}

console.log(promises) // (2) [undefined, Promise]

Promise.all(promises).then(() => {
  $("#dropdownBox").html(html);
});
编辑:有人指出我需要使用each代替forloop进行关闭,我尝试了但仍然无效。我试着做了

$.each(items, function(index){...}

items.forEach(function(index){...}

并相应地修改了循环中的内容,但没有运气。这篇文章(JavaScript closure inside loops – simple practical example)对我没有帮助。

1 个答案:

答案 0 :(得分:0)

如果类型不符合条件,您遇到的问题之一就是没有解决承诺。

您的for()循环也不会创建闭包,因此i将不会是您在请求完成时的预期

由于$.ajax返回一个promise,因此使用map()创建闭包和promise数组的反模式方法较少

// map array of promises
var promises = items.map((item) => {
  // return $.ajax promise
  return $.ajax({
    url: "url" + item,
    dataType: "json"
  }).then((data) => {
    let html = '';
    if (data.type == "mytype") {
      html += "<option value='" + data.id + "'>" + item + "</option>";
    }
    return html;
  });
});

Promise.all(promises).then((res) => {
  // res is array of  html (or empty) strings returned in each then() above
  $("#dropdownBox").html(res.join(''));
}).catch(err => console.log('At least one request failed'));

Demo