关于async这个库的mapLimit方法卡死的问题

代码如下:

var cheerio     = require('cheerio');
var superagent1 = require('superagent');
var eventproxy  = require('eventproxy');
var async       = require('async');
var utils       = require('./utils');
var install     = require('superagent-charset');
var fs             = require('fs');
var superagent  = install(superagent1);
var current_book = {};
var error_list = [];
var n=1;
superagent.get('http://www.biquku.com/0/330/').charset('gbk')
    .end(function (err, sres) {
      // 常规的错误处理
      if (err) {
        console.log(err);
      }
      // sres.text 里面存储着网页的 html 内容,将它传给 cheerio.load 之后
      // 就可以得到一个实现了 jquery 接口的变量,我们习惯性地将它命名为 `$`
      // 剩下就都是 jquery 的内容了
      var $ = cheerio.load(sres.text);
      var urls = $('#list a');  

      current_book.title = $('#maininfo h1').text()
      current_book.author = $('#info p').eq(0).text()
      current_book.update_time = $('#info p').eq(2).text()
      current_book.latest_chapter = $('#info p').eq(3).html()
      current_book.intro = $('#intro').html()
      current_book.chapters = [];

      for(var i = 0; i< urls.length; i++){
        var url = urls[i]
        var _url = $(url).attr('href')+"";
        var num = _url.replace('.html','');
        var title = $(url).text();
        current_book.chapters.push({
          num: num,
          title: title,
          url: _url
        })
      }
      console.log(current_book.chapters.length);

      async.mapLimit(current_book.chapters, 200, function (url, callback) {
          fetchUrl(url, callback);
        }, function (err, result) {
          console.log('final:');
          console.log(error_list);
        });
    });

function fetchUrl(url, callback){
    console.log(n++);
    if(n==1637){
        console.log(error_list)
    }
    superagent.get('http://www.biquku.com/0/330/' + url.num + '.html').charset('gbk').end(function(err,res){
        var timer = setTimeout(function(){
            callback(null);
        },500);
        if(!err){
            clearTimeout(timer)
            if(res){    
            if(res.text){
                var $ = cheerio.load(res.text);
                var content = $('#content').html();
                fs.writeFile('dist/0/330/' + url.num + '.html', content, function (err) {
                    if (err) throw err;
                    callback(null);
                  });

                }
            }else{
                error_list.push(url);
                callback(null);
            }
        }else{
            clearTimeout(timer)
            callback(null);
        }
        
    })
}

async.mapLimit最后的回调,不执行程序处于假死状态;在命令行显示如下:

clipboard.png

求大神们给分析一下为什么会这样子;

阅读 5.4k
2 个回答
新手上路,请多包涵

我也遇到这个问题,请问你解决了吗?

新手上路,请多包涵

我也用到了maplimit,不过我不是这么用的,
我的每个request会回来html,然后cheerio怼成数组,直接就callback了,
然后用maplimti把这个request包起来,得到一个大数组,怼mySql了

看代码楼主是想扒章节录接着扒内容(类似),个人建议先扒章节,所有章节完成之后再获取内容

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题