首页 > node爬虫异步问题

node爬虫异步问题

实现功能:

我对一个指定的url进行get请求,然后解析数据。
对里面的url存进一个数组里面,然后遍历这个数组的url 进行get进行获取数据。

问题描述:

 因为是并发请求,所以建立了一个变量count,如果count等于之前存放url数组长度,
 那么执行最后的done函数。 
 results [index] 和count应该是同步执行,然后执行done()。
 但为什么 done函数里面,打印results.length 为什么有点乱。

代码如下:

var http = require('http');
var cheerio = require('cheerio');
var url = require('url');
var express = require('express');
var pageUrl = 'http://shixi.info/';
var app = express();

//GET 请求指定pageUrl 
http.get(pageUrl , function(res) {
    var html = '';
    res.on('data', function(data) {
        html += data;
    });
    res.on('end', function() {
        callback(html);
    });
});

function callback(html) {
    var $ = cheerio.load(html);
    var arrUrl = [];
    var arrData = [];
    //解析pageUrl下数据 对指定url 存放进数组
    $('article').each(function(index, element) {
        var href = url.resolve(pageUrl , $(element).find('.entry-title a').attr('href'));
        arrUrl.push(href);
    });

    var count = 0;
    var results = [];
    function done() {
        console.log(results.length,count);
       /*
        7 1
        7 2
        8 3
        10 4
        10 5
        10 6
        10 7
        10 8
        10 9
        10 10
       */
        if (count == arrUrl.length) {
           app.get('/', function(req, res) {
               res.send(JSON.stringify(results));
           }).listen('8888', '127.0.0.1');
           console.log('done');
       }
    }

    //遍历 数组里面的url ,进行GET 请求
    arrUrl.forEach(function(item, index) {
        http.get(item, function(res) {
            var html = '';
            res.on('data', function(data) {
                html += data;
            });

            res.on('end', function() {
                var $ = cheerio.load(html);
                var title = $('.entry-title').text();
                //results [index] 和count应该是同步执行,然后执行done(), 但为什么 done函数里面打印results.length 为什么有点乱
                results[index] = {
                    url: item,
                    title: title
                };
                count++;
                done();
            }); 

        });
    });
}



根据目前的代码, 猜测产生这个问题的原因如下:
最后遍历arrUrl产生了 N个 http.get 而这个方法是异步的.
而在执行完成 将数据加入到result数据时,你是直接指定的下标的,
所以你在对于输出result.length会产生疑惑.
这个问题与下面的代码类似:

var a = [];
a[6] = 1;//设置下标为6的已经完成
console.log(a.length);//7
a[2] = 1;
console.log(a.length);//7
a[7] = 1;
console.log(a.length);//8
a[9] = 1;
console.log(a.length);//10
a[1] = 1;
console.log(a.length);//10
//....剩下的就是其他下标的

如果你的代码你有执行多次, 输出的顺序应该不是每次都一样的.

【热门文章】
【热门文章】