[英]nodejs looping with async function inside
I'm having a problem where for(var x=1; x < 6; x++)
is getting called because too fast axios.get()
is async, but I have no idea how to counter that without the solution being too complicated 我遇到一个问题,其中调用
for(var x=1; x < 6; x++)
是因为axios.get()
异步太快了,但是我不知道如何在解决方案不太复杂的情况下应对它
const axios = require("axios");
const cheerio = require("cheerio");
function imdbGetData(id) {
var title, show, $;
var arr = [];
var airdates = [];
show = {
seasons: []
};
axios.get(`http://www.imdb.com/title/${id}/`).then((body) => {
$ = cheerio.load(body.data);
title = $("div h1").text()
});
for(var x=1; x < 6; x++) {
console.log(x); // Will count too 1,2,3,4,5,6
url = `http://www.imdb.com/title/${id}/episodes?season=${x}`
axios.get(url).then((body) => {
$ = cheerio.load(body.data);
console.log(x);// 6, 6, 6, 6
$("div .info .airdate").each(function(index, item) {
var airdate = String($(this).text());
airdates.push(airdate.trim());
});
$(".info strong a").each(function(i, item){
var airdate = airdates[i];
var epsiode_name = $(this).text()
if (epsiode_name && !epsiode_name.includes("#"))
arr.push({epsiode_name, airdate});
});
show.seasons.push(arr);
arr = []
// console.log(show.seasons);
});
setTimeout(() => {console.log(show.seasons)}, 10000) // ghetto
}
}
// season = {
// seasons: [[ {epsiode_name} ], [{Epsiode name}]]
// }
imdbGetData("tt2193021");
You can construct and push all promises to array, and then use Promise.all(arrayOfPromises)
. 您可以构造并将所有的
Promise.all(arrayOfPromises)
推送到array,然后使用Promise.all(arrayOfPromises)
。 This way you will keep your asynchronous chain and you can easily handle results very similar to regular single asynchronous operation: 这样,您将保持异步链,并且可以轻松地处理与常规单个异步操作非常相似的结果:
var promises = [];
for (var x = 1; x < 6; x++) {
url = `http://www.imdb.com/title/${id}/episodes?season=${x}`
promises.push(axios.get(url));
}
Promise.all(promises)
.then(body => {
// all results of promises will be in 'body' parameter
})
.catch(err => console.error(err));
You can also use async/await (in newer versions of Node.js), so you can make the code a little easier to read, I've made a few little changes to update progress too. 您还可以使用async / await(在Node.js的较新版本中),以便使代码更易于阅读,我也做了一些小的更改以更新进度。
const axios = require("axios");
const cheerio = require("cheerio");
async function imdbGetData(id) {
var title, show, $;
var arr = [];
var airdates = [];
show = {
seasons: []
};
console.log('Getting from ' + `http://www.imdb.com/title/${id}/`);
let body = await axios.get(`http://www.imdb.com/title/${id}/`);
$ = cheerio.load(body.data);
title = $("div h1").text()
for(var x=1; x < 6; x++) {
console.log('Getting season: ' + x); // Will count too 1,2,3,4,5,6
url = `http://www.imdb.com/title/${id}/episodes?season=${x}`
let body = await axios.get(url);
$ = cheerio.load(body.data);
$("div .info .airdate").each(function(index, item) {
var airdate = String($(this).text());
airdates.push(airdate.trim());
});
$(".info strong a").each(function(i, item){
var airdate = airdates[i];
var epsiode_name = $(this).text()
if (epsiode_name && !epsiode_name.includes("#"))
arr.push({epsiode_name, airdate});
});
show.seasons.push(arr);
arr = []
}
console.log("Result: ", show.seasons);
}
imdbGetData("tt2193021");
You can simply use ES6 let
instead of var
, your code will be: 您可以简单地使用ES6
let
而不是var
,您的代码将是:
for(let i=0; i<length; i++){
asyncCall(function(){
console.log(i);// will print 0,1,2,3,...
});
}
Please check this article https://codeburst.io/asynchronous-code-inside-an-array-loop-c5d704006c99 请检查这篇文章https://codeburst.io/asynchronous-code-inside-an-array-loop-c5d704006c99
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.