我试图异步调用一些URL并收集结果。我已经用#34; Promises"完成了它。现在我试图绕过async.js。
这是一段剪辑代码:
var request = require("request"),
cheerio = require("cheerio");
// base_url = "http://de.indeed.com/Jobs?q="; // after equal sign for instance: sinatra&l=
var async = require('async');
/* search syntax:
- http://de.indeed.com/Jobs?q=node&l=berlin&radius=100
*/
var search_words = ["django", "python", "flask",
"rails", "ruby",
"node", "javascript", "angularjs", "react", "express", "meteor",
"java", "grails", "groovy",
"php", "symfony", "laravel" ];
var base_url = "http://de.indeed.com/Jobs?q=";
var stats = [];
async.each(search_words, function(keyword) {
var url = base_url + keyword + "&l=";
request( base_url + keyword + "&l=", function(err, resp, body) {
if (err) throw err;
$ = cheerio.load(body);
num_str = $("#searchCount")[0].children[0].data.split(" ").reverse()[0];
num_str = num_str.replace(/\./, "");
num_str = num_str.replace(/,/, "");
stats.push( [keyword, num_str] );
});
}, function(err) {
if (err) throw err;
console.log(stats);
});
根据this,我可以将回调函数作为async.each的最后一个参数传递,一旦数组被处理就会触发。
在我的情况下,回调似乎永远不会被触发。
Btw:Trevor Burnham在他的书中提到了#34; Async Javascript"函数asyn.forEach似乎已从async.js中删除了它?@robertklep给了我一个提示,给iteratee函数添加一个回调。 //这是工作版本:
var request = require("request"),
cheerio = require("cheerio");
// base_url = "http://de.indeed.com/Jobs?q="; // after equal sign for instance: sinatra&l=
var async = require('async');
/* search syntax:
- http://de.indeed.com/Jobs?q=node&l=berlin&radius=100
*/
var search_words = ["django", "python", "flask",
"rails", "ruby",
"node", "javascript", "angularjs", "react", "express", "meteor",
"java", "grails", "groovy",
"php", "symfony", "laravel" ];
var base_url = "http://de.indeed.com/Jobs?q=";
var stats = [];
async.each(search_words, function(keyword, callback) {
var url = base_url + keyword + "&l=";
request( url, function(err, resp, body) {
if (err) {
callback("ERROR in request");
} else {
$ = cheerio.load(body);
num_str = $("#searchCount")[0].children[0].data.split(" ").reverse()[0];
num_str = num_str.replace(/\./, "");
num_str = num_str.replace(/,/, "");
num = parseInt(num_str);
stats.push( [keyword, num] );
callback();
}
});
}, function(err) {
if(err) {
console.log(err);
} else {
stats_sorted = stats.sort( function(a, b) {
return b[1] - a[1];
});
console.log(stats_sorted);
}
});
答案 0 :(得分:0)
你错过了iteratee获得两个参数的部分:项目和一个回调。当iteratee完成时(或发生错误时)需要调用此回调:
async.each(search_words, function(keyword, callback) {
var url = base_url + keyword + "&l=";
request( base_url + keyword + "&l=", function(err, resp, body) {
if (err) return callback(err);
$ = cheerio.load(body);
num_str = $("#searchCount")[0].children[0].data.split(" ").reverse()[0];
num_str = num_str.replace(/\./, "");
num_str = num_str.replace(/,/, "");
stats.push( [keyword, num_str] );
return callback();
});
}, function(err) {
if (err) throw err;
console.log(stats);
});
鉴于您要将每个search_words
映射到一个值,您应该考虑使用async.map()
。这样,您就不会需要单独的stats
数组。
.each()
和.forEach()
曾经是同义词,但在最近的版本中,.forEach()
已被删除。
答案 1 :(得分:0)
非常确定一旦从请求
返回响应,您需要在回调中传回结果request( base_url + keyword + "&l=", function(err, resp, body) {
if (err) throw err;
$ = cheerio.load(body);
num_str = $("#searchCount")[0].children[0].data.split(" ").reverse()[0];
num_str = num_str.replace(/\./, "");
num_str = num_str.replace(/,/, "");
stats.push( [keyword, num_str] );
});