我使用Cheerio的每个函数来解析一些URL并将所有数据保存到MongoDB中。我的问题是cheerio每个函数都是同步的。并且我不知道解析何时结束以开始做其他事情。那么如何使这些函数异步?
request(URL, function (error, response, html) {
if (!error && response.statusCode == 200) {
var $ = cheerio.load(html);
var posturl = $('a',this).attr('href');
$('article').each(function(i, element){
parse_url(posturl, i);
});
}
});
这是我的Parse URL功能
function parse_url(url, i) {
request(url, function (error, response, html) {
if (!error && response.statusCode == 200) {
var $ = cheerio.load(html);
var title = $('article h1').text();
var postid = $('article').attr('id').substring(5);
var image = $('article img').attr('src');
var description = $('article p strong').text();
var json = { title : title, postid : postid, image : image, decription : description};
collection.insert(json,function (err, result) {
if (err) {
console.log(err);
} else {
}
});
}
});
}
答案 0 :(得分:2)
使用npm install async-foreach --save
安装async-foreach
包。在第一次请求中,将$('articles').each
方法更改为:
var forEach = require('async-foreach').forEach;
request(URL, function (error, response, html) {
if (!error && response.statusCode == 200) {
var $ = cheerio.load(html);
var posturl = $('a',this).attr('href');
forEach($('article').get(), function(article, index) {
this.async();
parse_url(article, index);
});
}
});
现在你仍然需要使parse_url
函数异步,因为它当前正在阻塞。要在Node中执行此操作,请使用process.nextTick(fn)
,这相当于浏览器setTimeout(fn, 0)
,但效率更高。
function parse_url(url, i) {
process.nextTick(function () {
request(url, function (error, response, html) {
if (!error && response.statusCode == 200) {
var $ = cheerio.load(html);
var title = $('article h1').text();
var postid = $('article').attr('id').substring(5);
var image = $('article img').attr('src');
var description = $('article p strong').text();
var json = { title : title, postid : postid, image : image, decription : description};
collection.insert(json,function (err, result) {
if (err) {
console.log(err);
} else {
}
});
}
});
});
}
希望能解决你的问题!