[英]How to sort a code execution in node.js Non-Blocking code?
我建立使用網絡爬蟲node.js
,但主要特征之一node.js
,是Non-Blocking
代碼,這是偉大的,但對我來說這是破壞我的計划。 這是我的程序過去的工作方式:
request
網站,並找到頁面上傳遞的所有公司的所有鏈接; for
循環,用於修改該公司的URL數組; request
,該request
將拋出公司URL數組以在每個公司頁面中查找所有產品URL; for
循環,用於修改該產品的URL數組; for
循環中有另一個請求,該請求拋出產品數組並獲取每個產品的價格,並將其存儲到dictionary(object)中,其中鍵是產品名稱,值是價格; 如您所見,我的每個步驟都取決於之前的步驟。 所以我需要做一些事情,使我的程序按照列出的順序運行。 我嘗試使用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
運行代碼?
如果您想使用JavaScript / node.js進行認真的編程,則必須深刻理解JS是異步的,除了代碼之外,所有其他事情都是並行發生的。
這意味着在您的情況下,除非所有代碼都已終止,否則不會調用回調。 因此,在for循環中調用異步函數應始終將所有警告燈變為紅色 !
這是正確設計的代碼:
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();
});
});
});
因為事情甚至可能變得更加復雜,所以我強烈建議您對本文進行研究。 確實值得一讀。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.