我使用node.js
构建了一个网络抓取工具,但是node.js
的一个主要功能是Non-Blocking
代码,这很棒,但在我的情况下它会破坏我的程序。以下是我的程序的工作方式:
request
并找到所有链接
所有通过该页面的公司; for
循环修改公司的URL数组; request
一系列公司URL,用于查找每个公司中的所有产品URL
页; for
循环来修改那些产品的URL数组; for
循环中的另一个请求
抛出一系列产品并获得每种产品的价格
将它存储到字典(对象)中,其中键是名称
产品和价值是价格; 正如您所看到的,我的每个步骤都取决于它之前的步骤。所以我需要做一些事情,所以我的程序按照我列出的顺序运行。我曾尝试使用callback
,但它并没有很好地结束。因为这是callback
:
function some_function(arg1, arg2, callback) {
var my_number = (arg1 - arg2) * arg2;
callback(my_number);
}
some_function(20, 15, function(num) {
console.log("callback called! " + num);
});
但我不认为如何进行具有6个功能的回调。也许有一种方法,但不是我对callback
的了解。这是我的程序的演示版本,没有callback
的:
var request = require('request');
var cheerio = require('cheerio');
var companiesUrls = [];
var url = '';
var companiesUrls2 = [];
var carsUrls = [];
var carsOwnerReview = {};
var carReviewUrl = [];
var site = '...'
var companiesPath = '/companies'
///step 1\\\
request(site+companiesPath, function(err, resp, body){
if(!err && resp.statusCode == 200){
var $ = cheerio.load(body);
$('a', '#group-content').each(function(){
var url = $(this).attr('href');
companiesUrls.push(url);
});
};
});
///step 2\\\
for(var i=0;i<companiesUrls.length;i+=2){
companiesUrls2.push(companiesUrls[i]);
};
///step 3\\\
for(var i=0;i<companiesUrls2.length;i++){
request(site+companiesUrls2[i], function(err, resp, body){
if(!err && resp.statusCode == 200){
var $ = cheerio.load(body);
$('h3.edition-title').children().children().each(function(){
var url = $(this).attr('href');
carsUrls.push(url);
});
};
});
};
///step 4\\\
for(var i=0;i<carsUrls.length;i++){
carReviewUrl.push(carsUrls[carsUrls.length-1].slice(0,-7)+'/owner-reviews');
};
///step 5\\\
for(var i=0;i<carReviewUrl.length;i++){
request(site+carReviewUrl[i], function(err, resp, body){
if(!err && resp.statusCode == 200){
var $ = cheerio.load(body);
var model = $('#page-title').text();
$('span.total-votes').children().each(function(){
var reviewNum = $(this).text();
carsOwnerReview[model] = reviewNum;
});
};
});
}
///step 6\\\
var keysSorted = Object.keys(carsOwnerReview).sort(function(a,b){return carsOwnerReview[a]-carsOwnerReview[b]});
var keysSortedReversed = keysSorted.reverse();
所以我的问题是:如何在我的订单中使用node.js
运行我的代码?
答案 0 :(得分:0)
如果你想用JavaScript / node.js认真编程,你必须深刻理解JS是异步的,除了你的代码之外,一切都是并行的。
这意味着在您的情况下,除非您的所有代码都已终止,否则不会调用您的回调。因此,在for-loop中调用异步函数应始终将所有警告灯 RED !
以下是您正确设计的代码:
var request = require('request');
var cheerio = require('cheerio');
var companiesUrls = [];
var url = '';
var companiesUrls2 = [];
var carsUrls = [];
var carsOwnerReview = {};
var carReviewUrl = [];
var site = '...'
var companiesPath = '/companies'
///step 1\\\
request(site+companiesPath, function(err, resp, body){
if(!err && resp.statusCode == 200){
var $ = cheerio.load(body);
$('a', '#group-content').each(function(){
var url = $(this).attr('href');
companiesUrls.push(url);
});
};
///step 2\\\
for(var i=0;i<companiesUrls.length;i+=2){
companiesUrls2.push(companiesUrls[i]);
};
///step 3\\\
function processCompaniesUrls2( i, callback_pcu2 ) {
if( i<companiesUrls2.length ) {
request(site+companiesUrls2[i], function(err, resp, body){
if(!err && resp.statusCode == 200){
var $ = cheerio.load(body);
$('h3.edition-title').children().children().each(function(){
var url = $(this).attr('href');
carsUrls.push(url);
});
};
processCompaniesUrls2( i+1, callback_pcu2 );
});
} else {
callback_pcu2();
}
}
processCompaniesUrls2( 0, function() {
///step 4\\\
for(var i=0;i<carsUrls.length;i++){
carReviewUrl.push(carsUrls[carsUrls.length-1].slice(0,-7)+'/owner-reviews');
};
///step 5\\\
function processCarReviewUrl( i, callback_pcru ) {
if( i<carReviewUrl.length ) {
request(site+carReviewUrl[i], function(err, resp, body){
if(!err && resp.statusCode == 200){
var $ = cheerio.load(body);
var model = $('#page-title').text();
$('span.total-votes').children().each(function(){
var reviewNum = $(this).text();
carsOwnerReview[model] = reviewNum;
});
};
processCarReviewUrl( i+1, callback_pcru );
});
} else {
callback_pcru();
}
}
processCarReviewUrl( 0, function() {
///step 6\\\
var keysSorted = Object.keys(carsOwnerReview).sort(function(a,b){return carsOwnerReview[a]-carsOwnerReview[b]});
var keysSortedReversed = keysSorted.reverse();
});
});
});
因为事情甚至会变得更复杂,所以我强烈推荐this article的研究。这真的值得一读。