Javascript / NodeJS回调函数和循环

时间:2017-01-18 14:36:47

标签: javascript jquery node.js web-scraping cheerio

我已经使用cheeriorequest创建了一个网络漫游器,我现在正尝试在网址数组上实现循环。

不幸的是,我对我的通话和回叫做错了,但我无法弄清楚是什么。

这是我的代码:

var getWebData = function(url) {
  var i = 1;
  var data = [];
  for (c = 0; c < url.length; c++) {
    data[i] = request(url[c], function(err, resp, body) {
          console.log('ok');
           if (!err) {
             console.log('there');
             var $ = cheerio.load(body);
             $('.text').each(function(i, element) {
               var jsObject = { name : "", description : "", price: "", categorie: "", pricePerKg: "", capacity: "", weight: "", scrapingDate : "", url: ""};
               var name = 'TESTOK';
               jsObject.name = name;
               data.push(jsObject);
            })
            return data;
         }
         console.log('but');
       });
    i++;
  }
  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');

请注意,我的任何调试都不会打印。

有没有人知道我的代码中有什么问题?我该怎么做才能让它运作?

3 个答案:

答案 0 :(得分:1)

请求是Aysnc

var json = JSON.stringify(data);
fs.writeFile('output.json', JSON.stringify(json, null, 4), function(err) {
  console.log('File successfully written!');
})

上面的代码在for循环完成执行之前运行并填充数据对象。 在循环完成执行时尝试执行这段代码。

首先运行此命令npm install async --save

    var async = require('async');

    var getWebData = function(url){
    var data = [];
    async.eachSeries(url, function(urlSingle , cb){
       request(urlSingle, function(err, resp, body) {
        //write your logic here and push data in to data object
        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!');
        });
    });
    }

答案 1 :(得分:1)

我一直在阅读Asif的回答和评论。该实现是正确的,但你不必增加c变量,如果你之前启动c = 0,所有请求将是url [0]。

请注意,async.eachSeries在&#34; urlsingle&#34;中回调数组url的每个元素。回调,所以你应该使用

request(urlsingle, ...

或考虑使用async.eachOf,它为您提供数组中每个元素的索引。

检查任何疑问http://caolan.github.io/async/

的异步文档

答案 2 :(得分:0)

for (c = 0; c < url.length; c++) {
    ……
}

你应该这样改变:

var async = require('asycn');
async.map(url,
function(item, callback) {
    data[i] = request(url[c],
    function(err, resp, body) {
        console.log('ok');
        if (!err) {
            console.log('there');
            var $ = cheerio.load(body);
            $('.text').each(function(i, element) {
                var jsObject = {
                    name: "",
                    description: "",
                    price: "",
                    categorie: "",
                    pricePerKg: "",
                    capacity: "",
                    weight: "",
                    scrapingDate: "",
                    url: ""
                };
                var name = 'TESTOK';
                jsObject.name = name;
                data.push(jsObject);
            }) callback(err, data);
        }
        console.log('but');
    });
    i++;
},function(err, results) {
    if(err){
        console.log(err);
    }
});
循环中的

是一个耗时的操作。你应该使用异步操作。