Javascript/NodeJS 回调函数和循环

Javascript/NodeJS callbacks function and loop

我用 cheeriorequest 制作了一个网络爬虫,我现在正在尝试在 url 的数组上实现一个循环。

不幸的是,我的呼叫和回叫有问题,但我不知道是什么。

这是我的代码:

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

请注意,我的任何调试打印都没有打印出来。

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

请求是 Aysnc

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

上面的代码 运行s 在 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!');
        });
    });
    }

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

注意async.eachSeries在"urlsingle"回调中回调数组url的每个元素,所以你应该使用

request(urlsingle, ...

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

检查异步文档是否有任何疑问http://caolan.github.io/async/

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

在循环中比较耗时operation.you应该使用异步操作