实现功能:
我对一个指定的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
//....剩下的就是其他下标的
如果你的代码你有执行多次, 输出的顺序应该不是每次都一样的.