【问题标题】:How to make an asynchronous function in Node JS如何在 Node JS 中创建一个异步函数
【发布时间】:2015-10-15 20:19:59
【问题描述】:

我使用 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);

    });            

  }
});

这是我的解析 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 {

      }


    });  
  }
});

}

【问题讨论】:

    标签: node.js mongodb asynchronous cheerio


    【解决方案1】:

    使用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 {
    
              }
            });
          }
        });
      });
    }
    

    希望能解决你的问题!

    【讨论】:

    • 我想在一切完成后显示控制台日志消息,我应该在哪里写?
    • forEach 函数接受 3 个参数。第一个是要迭代的数组,第二个是要在每个项目上执行的函数,最后一个是完成函数,把你的 console.log 放在那里。
    • 这不起作用!当我使用 this.async();在第一项上的 foreach 功能块上,当我删除它时,控制台日志没有出现在正确的时间
    猜你喜欢
    • 2020-04-28
    • 2020-05-30
    • 2018-05-15
    • 1970-01-01
    • 2020-06-01
    • 2017-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多