Javascript NodeJS循环中的异步双回调

Javascript NodeJS循环中的异步双回调,javascript,node.js,asynchronous,callback,cheerio,Javascript,Node.js,Asynchronous,Callback,Cheerio,今天我要进入我的网络游戏的下一步 我已经在使用async在一个url数组上循环,我会在这个回调中再次循环,并等待它在重新启动之前执行 我不知道如何使用两个回调函数 这是我的代码: var getWebData = function(url) { var data = []; async.eachSeries(url, function(urlSingle, cb) { request(urlSingle, function(err, resp, body) {

今天我要进入我的网络游戏的下一步

我已经在使用
async
在一个url数组上循环,我会在这个回调中再次循环,并等待它在重新启动之前执行

我不知道如何使用两个回调函数

这是我的代码:

   var getWebData = function(url) {
   var data = [];
   async.eachSeries(url, function(urlSingle, cb) {
      request(urlSingle, function(err, resp, body) {
        if (!err) {
          var $ = cheerio.load(body);
          var categoriesURL = [];
            $('.ombre_menu li').each(function(i, element) {
              $(this).find('.nav_sous-menu_bloc li a').each(function(i, element) {
                categoriesURL.push('https://blabla' + $(this).attr('href'));
              })

              // I WANT TO LOOP on the categoriesURL array HERE

                var jsObject = { name : "", description : "", price: "", categorie: "", liter: "", kilo: "", pricePer: "", quantity: "", capacity: "", promotion: "", scrapingDate : "", url: "" };
                data.push(jsObject);
            })
        }
       cb();
      })
   }, function() {
    // this will rum when loop is done
    var json = JSON.stringify(data);
    fs.writeFile('output.json', JSON.stringify(json, null, 4), function(err) {
        console.log('File successfully written!');
     });
   });
}

getWebData(url);
app.listen('8080');
有人知道我该怎么做吗


谢谢

您可以使用嵌套的eachSeries。像这样:

var getWebData = function(url) {
   var data = [];
   async.eachSeries(url, function(urlSingle, cb) {
      request(urlSingle, function(err, resp, body) {
        if (!err) {
          var $ = cheerio.load(body);
          var categoriesURL = [];
            $('.ombre_menu li').each(function(i, element) {
              $(this).find('.nav_sous-menu_bloc li a').each(function(i, element) {
                categoriesURL.push('https://blablablac' + $(this).attr('href'));
              })
              async.eachSeries(caturl, function(categoriesURL, cb2) {
                      //Do whatever you want to do here
                      cb2();
              },  function() {
                 //You can apply if and else for err an according to that you can set your callback responce here
                 cb();
              };
            })
        }
      })
   }, function() {
    // this will rum when loop is done
    var json = JSON.stringify(data);
    fs.writeFile('output.json', JSON.stringify(json, null, 4), function(err) {
        console.log('File successfully written!');
     });
   });
}

getWebData(url);
app.listen('8080');

在代码中做了几处更改:

  • 使用
    .mapSeries
    代替
    .eachSeries
    。通过这种方式,您可以按照与输入数组相同的顺序从迭代器函数中获取数据。意味着您将得到[4,9],用于平方函数的输入[2,3],而不是[9,4]
  • 将代码分解为函数,以便每个函数执行一个特定任务
  • 已将categoriesURL处理移出循环1
  • 早点回来。它提高了代码的可读性<代码>如果(错误)返回回调(错误)


  • 谢谢Pankaj的回答,我不想在我的第二个循环之后有另一个函数。也许我可以从第二个代码中取出cb()?非常感谢@Sanghrash的回答,但我不知道如何使用此代码…你有什么具体的疑问吗?我试过你的代码,用url替换urlSingle(因为我有引用错误:urlSingle没有定义),看起来我有一个无限循环@SangharshDid您从
    processCategoryUrl
    方法调用
    callback
    ?我现在已经把
    callback()
    放进去了。稍后用您的实现替换它。现在试试。如果成功,我必须执行return callback()吗?
    function getWebData(url) {
    
      // Using .mapSeries in place of .eachSeries as you seem to want to get data from iterator function
      async.mapSeries(url, processUrl, function(err, results) {
        // this will rum when loop is done
        var json = JSON.stringify(results);
        fs.writeFile('output.json', JSON.stringify(json, null, 4), function(err) {
          console.error('Error', err);
          console.log('File successfully written!');
        });
      });
    }
    
    function processUrl(url, callback) {
      request(url, function(err, resp, body) {
        if (err) // Return simple cases early; Improves code readability
          return callback(err); // or return callback(); -- if you don't want to send error upwards
    
        var $ = cheerio.load(body);
        var categoriesURL = [];
    
        $('.ombre_menu li')
          .each(function(i, element) { // loop 1
            $(this)
              .find('.nav_sous-menu_bloc li a')
              .each(function(i, element) { // loop 2
                categoriesURL.push('https://blablablac' + $(this)
                  .attr('href'));
              }) // loop 2 end
    
          }) // loop 1 end
        // I WANT TO LOOP ON THE categoriesURL ARRAY HERE
        // Using .mapSeries in place of .eachSeries for same above reason
        async.mapSeries(categoriesURL, processCategoryUrl, function(err, results) {
          if (err)
            return callback(err);
          // This function is called after process array categoriesURL
    
          // Do what you want here then call callback provided to this method
          return callback(null, results);
        })
      })
    }
    
    function processCategoryUrl(categoryUrl, callback) {
      // Just process categoryUrl here and call callback with error or results
      return callback();
    }
    
    getWebData(url);
    app.listen('8080');