下面是一个函数,它应该使用chaptersArry
来获取每个章节的项目,并将它们放入一个新的数组中*原始章节数据和项目数据一起*称为itemsArr
function get_items(chaptersArry){
for ( var 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';
$.get(api_url, function(items) {
// 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]
});
}
});
}
}
与 Kamyar Infinity 的答案一样,您需要使用闭包或使用带有 let
的块范围来获取$.get()
回调中的正确数据,但是,这不是问题的症结所在。由于您需要异步返回数据,因此需要使用承诺。以下是您可以做到这一点的方法:
工作演示
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));
});
我看到的主要问题是,当你使用var
时,循环结束时l-1
ii
的值,因为var
不是基于块的声明,并且所有函数都将获得同一变量的值。现在,您有两种选择。
使用 let
,如果你可以使用 ES6:
for ( let ii = 0, l = chaptersArry.length; ii < l; ii++ ) {
...
如果没有,您可以使用IIFE
:
for ( var ii = 0, l = chaptersArry.length; ii < l; ii++ ) {
(function(ii){
...
})(ii);
}
您可以使用 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闭包相关。