Javascript结合了来自不同范围的多个数组

时间:2017-05-12 16:57:22

标签: javascript jquery arrays

下面是一个函数,它应该使用chaptersArry来获取每个章节项目,并将它们放入一个新的数组 *中,原始章节数据和项目数据一起* 称为{{1 }}

itemsArr

3 个答案:

答案 0 :(得分:2)

与Kamyar Infinity的回答一样,您需要使用闭包或使用let的块范围来获取$.get()回调中的正确数据,但这不是问题的关键。由于您需要异步返回数据,因此需要使用promises。以下是如何做到这一点:

Working Demo

function get_items(chaptersArry){
  return new Promise(function (resolve, reject) {
    var promises = [];
    for (let ii = 0, l = chaptersArry.length; ii < l; ii++ ) {
      console.log(chaptersArry[ii].id+" *****");  // this returns the correct data

      // now I am using each chapter ID from above to $.get the chapter items..... 
      var api_url = '/collections/' + chaptersArry[ii].id + '/contents.json';
      var promise = new Promise(function (_resolve, _reject) {
        $.get(api_url, function(items) {
          var itemsArr = [];
          // for each chapter loop through items and push them to itemsArr.
          for ( var i = 0, l = items.collection_contents.length; i < l; i++ ) {
            itemsArr.push({
              series_id : chaptersArry[ii].series_id, 
              series_name : chaptersArry[ii].series_name,
              chapter_id : chaptersArry[ii].id, 
              chapter_name : chaptersArry[ii].name,
              chapter_display_name : chaptersArry[ii].display_name,
              chapter_data : items.collection_contents[i]
            });
          }
          _resolve(itemsArr);
        });
      });
      promises.push(promise);
    }
    Promise.all(promises).then(function (values) {
      resolve(values);
    });
  });
}

get_items(chaptersArry).then(function (results) {
  // flatten array of results from each $.get()
  console.log([].concat(...results));
});

答案 1 :(得分:1)

我看到的主要问题是,当您使用var时,ii的值在循环结束时将为l-1,因为var是不是基于块的声明,并且所有函数都将获得相同变量的值。现在,您有两种选择。

如果您可以使用ES6,则可以使用let

for ( let ii = 0, l = chaptersArry.length; ii < l; ii++ ) {
...

如果没有,您可以使用IIFE

for ( var ii = 0, l = chaptersArry.length; ii < l; ii++ ) {
    (function(ii){
       ...
     })(ii);
}

答案 2 :(得分:1)

您可以使用Function.bind

$.get(api_url, function(items) {
  var ii = this;
  // for each chapter loop through items and push them to itemsArr.
  for ( var i = 0, l = items.collection_contents.length; i < l; i++ ) {
    console.log(chaptersArry[ii].id); // returns incorrect data 
    itemsArr.push({
        series_id : chaptersArry[ii].series_id, 
        series_name : chaptersArry[ii].series_name,
        chapter_id : chaptersArry[ii].id, 
        chapter_name : chaptersArry[ii].name,
        chapter_display_name : chaptersArry[ii].display_name,
        chapter_data : items.collection_contents[i]
    });
  }
}.bind(ii));

这个问题有更好的解决方案。但这可能是最简单的。这可能是重复的,因为它与JavaScript闭包相关。