如何用多个 api 调用填充数组?
How do I fill an array with multiple api calls?
我在尝试弄清楚如何通过连续调用 spotify api 来填充此 'artists' 数组时遇到困难。我试图用用户保存的库中的每个艺术家填充 'artists' 数组。通话的工作方式是,每次通话将 return 一组最多 50 位艺术家。但是,当我在这里填充数组然后尝试将新的 i 值传递给 getUserData 函数时,我认为 i 值没有更新并且由于某种原因我的 'artists' 数组只填充了 226,而'total' 我的测试用例的值为 276。有人可以帮我弄这个吗?我认为这可能是一个范围问题,但我不知道在哪里。提前致谢!
var i = 0;
function getUserData(accessToken, i) {
return $.ajax({
url: 'https://api.spotify.com/v1/me/tracks?limit=50&offset=' + i,
headers: {
'Authorization': 'Bearer ' + accessToken
}
});
}
var artists = [];
loginButton.addEventListener('click', function() {
login(function(accessToken) {
getUserData(accessToken, i)
.then(function(response) {
var total = response.total;
while(i < total) {
i+=50;
getUserData(accessToken, i)
.then(function(response) {
total = response.total;
alert(total); //testing
loginButton.style.display = 'none';
for (var j = 0; j < 50 && artists.length < total; j++){
artists.push(response.items[j].track.album.artists[0].name);
}
alert(artists[7] + artists.length); //testing
alert(artists[artists.length - 1]); //testing
});
}
});
});
});
感谢您的帮助!
while 循环中的第一个 getUserData
从 i = 50
开始 - 因此前 50 个不会被推入 artists
数组
添加
for (var j = 0; j < 50 && artists.length < total; j++) {
artists.push(response.items[j].track.album.artists[0].name);
}
在 while 循环之前 - 像这样
var artists = [];
loginButton.addEventListener('click', function() {
login(function(accessToken) {
var i = 0;
getUserData(accessToken, i)
.then(function(response) {
var total = response.total;
// added code to store the first 50 artists
for (var j = 0; j < 50 && artists.length < total; j++) {
artists.push(response.items[j].track.album.artists[0].name);
}
// end added code
while (i < total) {
i += 50;
getUserData(accessToken, i)
.then(function(response) {
total = response.total;
alert(total); //testing
loginButton.style.display = 'none';
for (var j = 0; j < 50 && artists.length < total; j++) {
artists.push(response.items[j].track.album.artists[0].name);
}
alert(artists[7] + artists.length); //testing
alert(artists[artists.length - 1]); //testing
});
}
});
});
});
唯一的问题是艺术家的顺序可能是 "wrong",因为其中一个异步 getUserData 可能比下一个花费更长的时间(网络问题不可预测)
您可以重写代码以使用 Array#map
、Array#concat
和 $.when
- 并通过这样做保留数据的顺序
I'm assuming response.total
is the total number of tracks, regardless of the offset and limit as this is implied by your code
loginButton.addEventListener('click', function() {
login(function(accessToken) {
loginButton.style.display = 'none';
var arr = [getUserData(accessToken, i)];
arr[0]
.then(function(response) {
for (var i = 50; i < response.total; i += 50) {
arr.push(getUserData(accessToken, i));
}
$.when.apply($, arr)
.then(function() {
var artists = [].concat.apply([], [].map.call(arguments, function(response) {
return response.items.map(function(item) {
return item.track.album.artists[0].name;
});
}));
// artists array is filled, now do what you need
});
})
.catch(function(err) {
// handle errors here
});
});
});
同上,但使用原生 Promise.all
loginButton.addEventListener('click', function() {
login(function(accessToken) {
loginButton.style.display = 'none';
var arr = [getUserData(accessToken, i)];
arr[0]
.then(function(response) {
for (var i = 50; i < response.total; i += 50) {
arr.push(getUserData(accessToken, i));
}
Promise.all(arr).then(function(chunks) {
var artists = [].concat.apply([], chunks.map(function(response) {
return response.items.map(function(item) {
return item.track.album.artists[0].name;
});
}));
// artists array is filled, now do what you need
});
})
.catch(function(err) {
// handle errors here
});
});
});
我在尝试弄清楚如何通过连续调用 spotify api 来填充此 'artists' 数组时遇到困难。我试图用用户保存的库中的每个艺术家填充 'artists' 数组。通话的工作方式是,每次通话将 return 一组最多 50 位艺术家。但是,当我在这里填充数组然后尝试将新的 i 值传递给 getUserData 函数时,我认为 i 值没有更新并且由于某种原因我的 'artists' 数组只填充了 226,而'total' 我的测试用例的值为 276。有人可以帮我弄这个吗?我认为这可能是一个范围问题,但我不知道在哪里。提前致谢!
var i = 0;
function getUserData(accessToken, i) {
return $.ajax({
url: 'https://api.spotify.com/v1/me/tracks?limit=50&offset=' + i,
headers: {
'Authorization': 'Bearer ' + accessToken
}
});
}
var artists = [];
loginButton.addEventListener('click', function() {
login(function(accessToken) {
getUserData(accessToken, i)
.then(function(response) {
var total = response.total;
while(i < total) {
i+=50;
getUserData(accessToken, i)
.then(function(response) {
total = response.total;
alert(total); //testing
loginButton.style.display = 'none';
for (var j = 0; j < 50 && artists.length < total; j++){
artists.push(response.items[j].track.album.artists[0].name);
}
alert(artists[7] + artists.length); //testing
alert(artists[artists.length - 1]); //testing
});
}
});
});
});
感谢您的帮助!
while 循环中的第一个 getUserData
从 i = 50
开始 - 因此前 50 个不会被推入 artists
数组
添加
for (var j = 0; j < 50 && artists.length < total; j++) {
artists.push(response.items[j].track.album.artists[0].name);
}
在 while 循环之前 - 像这样
var artists = [];
loginButton.addEventListener('click', function() {
login(function(accessToken) {
var i = 0;
getUserData(accessToken, i)
.then(function(response) {
var total = response.total;
// added code to store the first 50 artists
for (var j = 0; j < 50 && artists.length < total; j++) {
artists.push(response.items[j].track.album.artists[0].name);
}
// end added code
while (i < total) {
i += 50;
getUserData(accessToken, i)
.then(function(response) {
total = response.total;
alert(total); //testing
loginButton.style.display = 'none';
for (var j = 0; j < 50 && artists.length < total; j++) {
artists.push(response.items[j].track.album.artists[0].name);
}
alert(artists[7] + artists.length); //testing
alert(artists[artists.length - 1]); //testing
});
}
});
});
});
唯一的问题是艺术家的顺序可能是 "wrong",因为其中一个异步 getUserData 可能比下一个花费更长的时间(网络问题不可预测)
您可以重写代码以使用 Array#map
、Array#concat
和 $.when
- 并通过这样做保留数据的顺序
I'm assuming
response.total
is the total number of tracks, regardless of the offset and limit as this is implied by your code
loginButton.addEventListener('click', function() {
login(function(accessToken) {
loginButton.style.display = 'none';
var arr = [getUserData(accessToken, i)];
arr[0]
.then(function(response) {
for (var i = 50; i < response.total; i += 50) {
arr.push(getUserData(accessToken, i));
}
$.when.apply($, arr)
.then(function() {
var artists = [].concat.apply([], [].map.call(arguments, function(response) {
return response.items.map(function(item) {
return item.track.album.artists[0].name;
});
}));
// artists array is filled, now do what you need
});
})
.catch(function(err) {
// handle errors here
});
});
});
同上,但使用原生 Promise.all
loginButton.addEventListener('click', function() {
login(function(accessToken) {
loginButton.style.display = 'none';
var arr = [getUserData(accessToken, i)];
arr[0]
.then(function(response) {
for (var i = 50; i < response.total; i += 50) {
arr.push(getUserData(accessToken, i));
}
Promise.all(arr).then(function(chunks) {
var artists = [].concat.apply([], chunks.map(function(response) {
return response.items.map(function(item) {
return item.track.album.artists[0].name;
});
}));
// artists array is filled, now do what you need
});
})
.catch(function(err) {
// handle errors here
});
});
});