如何在Node JS中创建异步函数

时间:2015-10-15 11:24:44

标签: node.js mongodb asynchronous cheerio

我使用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 {

      }


    });  
  }
});

}

1 个答案:

答案 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 {

          }
        });
      }
    });
  });
}

希望能解决你的问题!