簡體   English   中英

node.js內部循環帶有異步功能

[英]nodejs looping with async function inside

我遇到一個問題,其中調用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");

您可以構造並將所有的Promise.all(arrayOfPromises)推送到array,然后使用Promise.all(arrayOfPromises) 這樣,您將保持異步鏈,並且可以輕松地處理與常規單個異步操作非常相似的結果:

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));

您還可以使用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");

您可以簡單地使用ES6 let而不是var ,您的代碼將是:

for(let i=0; i<length; i++){
   asyncCall(function(){
    console.log(i);// will print 0,1,2,3,...
    });
}

請檢查這篇文章https://codeburst.io/asynchronous-code-inside-an-array-loop-c5d704006c99

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM