JS 循环遍历 API 中的 fetch
2020-11-30
57
最近我一直在研究这段代码,我非常 困惑 和沮丧,为什么它会 随机 地对输出进行排序,但后来我意识到它会加载加载速度最快的频道,然后它的 索引 变为 0,下一个加载速度最快的频道变为 1,下一个加载速度最快的频道变为 2,依此类推。
var channels = [
"UCIgnIPif1LQxkdbvBmGNNuA", // channel 1
"UC_Qs0JhHoysG4LItMgGMHHQ", // channel 2
"UC_puGdwVL1kc5VRhaZc6Arw", // channel 3
"UCQvwHZVCrljzvaLVX33Qaaw" // channel 4
];
var key = "cant share but i will tell you the output of the code"
var subCounts = [];
function getSubs(id, key){
for(var i = 0; i < channels.length; i++){
fetch('https://www.googleapis.com/youtube/v3/channels?part=statistics&id='+channels[i]+'&key='+key+'')
.then(response => {
return response.json()
}).then(data => {
//name[i].innerHTML =
subCounts.push(data['items'][0].statistics.subscriberCount);
});
} // for loop close
}
setTimeout(function(){
console.log(subCounts);
// output example: 4, 5, 6, 7
// another output: 5, 7, 6, 4
// another output: 7, 4, 5, 6
}, 1500) // good enough for the fetch to load
它只是随机的(先加载的频道排在 前面 )。
但我希望它这样做:
我希望它根据频道的顺序加载。因此,频道 1 需要先加载,然后是频道 2,然后是频道 3,等等。而不是先加载哪个频道。
任何帮助、建议和提示都将不胜感激。
3个回答
假设您可以等待所有请求完成后再开始处理其响应
,那么
Promise.all
应该可以让您实现您的目标。下面是使用
Promise.all
大致重写的代码:
var channels = [
"UCIgnIPif1LQxkdbvBmGNNuA", // channel 1
"UC_Qs0JhHoysG4LItMgGMHHQ", // channel 2
"UC_puGdwVL1kc5VRhaZc6Arw", // channel 3
"UCQvwHZVCrljzvaLVX33Qaaw" // channel 4
];
var key = "cant share but i will tell you the output of the code"
var subCounts = [];
function getSubs(id, key) {
var requests = [];
var currentRequest;
for (var i = 0; i < channels.length; i++) {
currentRequest = fetch('https://www.googleapis.com/youtube/v3/channels?part=statistics&id=' + channels[i] + '&key=' + key + '');
requests.push(currentRequest);
} // for loop close
Promise.all(requests).then((responses) => {
for (let j = 0; j < responses.length; j++) {
const currentResponse = responses[j];
const data = currentRequest.json();
subCounts.push(data['items'][0].statistics.subscriberCount);
}
});
}
setTimeout(function () {
console.log(subCounts);
// output example: 4, 5, 6, 7
// another output: 5, 7, 6, 4
// another output: 7, 4, 5, 6
}, 1500) // good enough for the fetch to load
请注意,我通常选择使用现代变量声明
let
/
const
- 您通常不会希望将较旧的
var
混合到代码中
let
/
const
,因此最好更新所有内容,或者不太理想的是,对所有声明使用
var
。此外,这显然没有经过测试,因此可能需要根据您的目的进行一些修改。
如果每毫秒都很重要,并且您需要按顺序处理它们,但一旦它们进入,就需要以不同的方式编写。如果您这样回复,我可以尝试整理一个 POC。
Alexander Nied
2020-11-30
这对于
Promise.all
来说是一个很好的用途
(docs)
类似于:
Promise.all(
channels.map(
channel => fetch('https://www.googleapis.com/youtube/v3/channels?part=statistics&id='+channel+'&key='+key+'')
)
)
.then(Promise.all((responses) => responses.map(response => response.json()))
.then(responses => {
// now responses is an array in order of the results that you can process as you wish
});
另一种方法是使
subCounts
的长度与
channels
的长度相同,并将
i
第通道结果放置在
subCounts
数组中的索引
i
处。
rb612
2020-11-30
您可以使用异步等待,
var data = await fetch('https://www.googleapis.com/youtube/v3/channels?part=statistics&id='+channels[i]+'&key='+key+'')
.then(response => {
return response.json()
}).then(data => {
//name[i].innerHTML =
});
subCounts.push(data['items'][0].statistics.subscriberCount);
Naga Raj
2020-11-30