Node.js文件写入问题,写不完整

时间:2014-12-29 12:26:43

标签: node.js cheerio

我是node.js的新手。我写了一个刮板,如下所示,结果它产生的不好。所有条目都没有被写入,并且不完整的损坏数据被添加到文件中,但是在控制台日志中如果没有单独的数据提取。

原始文件是我添加的所有代码部分的复杂样本,以显示我的逻辑,请告诉我做错了什么。

var request = require('request');
var cheerio = require('cheerio');

var url = 'http://example.com/index.html';
request(url, function(err, resp, body) {
    if (err)
        throw err;
    $ = cheerio.load(body);   
    var categoryname = $('#mcat span').html();
    var subcategoryname = $('span.arrow').html();
    $('.listing').each(function() {
    var companyname = $(this).find('.company-name > span').html();
    var compwebsite = $(this).find('.company-link > a').html();
    var phonelumber = "+91-" + $(this).find('span[itemprop="telephone"]').html();


        var data = categoryname + ", " + subcategoryname + ", " + companyname + ", " + phonelumber;
        var fs = require('fs');
        fs.writeFile("data.txt", data, function(err) {
        if(err) {
        console.log("Error: "+err);
        } else {
        console.log("Success!");
        }
        });
     });
});

2 个答案:

答案 0 :(得分:1)

.each被同步调用,因此它是阻塞的。但是fs.writeFile是异步调用的,所以它会使你的数据变得混乱,但是它不会是不完整的。

<强>解决方案

使用回拨

request(url, function(err, resp, body) {
    if (err)
        throw err;
    $ = cheerio.load(body);
    var categoryname = $('#mcat span').html();
    var subcategoryname = $('span.arrow').html();
    var count = 0;
    var len = $('.listing').length;
    var data = '';
    $('.listing').each(function() {
        count++;
        var companyname = $(this).find('.company-name > span').html();
        var compwebsite = $(this).find('.company-link > a').html();
        var phonelumber = "+91-" + $(this).find('span[itemprop="telephone"]').html();
        data += categoryname + ", " + subcategoryname + ", " + companyname + ", " + phonelumber + "\r\n";
        if(count == len)
             writeData(data);
    });
});

function writeData(data) {
    var fs = require('fs');
    fs.writeFile("data.txt", data, function(err) {
        if (err) {
            console.log("Error: " + err);
        } else {
            console.log("Success!");
        }
    });
}
  1. 使用async模块。它具有各种可用的功能来应用回调并获得必要的结果。

答案 1 :(得分:0)

我认为你也可以做得更容易(只需在每个循环后调用writedata函数(因为cherio的each()是同步的,所以没有问题)

    request(url, function(err, resp, body) {
    if (err)
        throw err;
    $ = cheerio.load(body);
    var categoryname = $('#mcat span').html();
    var subcategoryname = $('span.arrow').html();
    var data = '';
    $('.listing').each(function() {
        var companyname = $(this).find('.company-name > span').html();
        var compwebsite = $(this).find('.company-link > a').html();
        var phonelumber = "+91-" + $(this).find('span[itemprop="telephone"]').html();
        data += categoryname + ", " + subcategoryname + ", " + companyname + ", " + phonelumber + "\r\n";
    });
    writeData(data);
});

function writeData(data) {
    var fs = require('fs');
    fs.writeFile("data.txt", data, function(err) {
        if (err) {
            console.log("Error: " + err);
        } else {
            console.log("Success!");
        }
    });
}