并发控制问题
发布于 6 年前 作者 tingzhong666 2887 次浏览 来自 问答

抓取 cnode 社区首页的 40 条文章链接 然后再对 40 条链接发起请求 然后发现同时请求太多,会返回 503 我就直接折腾,封装了一个控制 同时请求 的数量的函数,应该是叫 并发控制 吧。 不过,有点问题,当我设置为 7 个并发时,就少了 7 条返回,设置为 2 条并发时,就少了 2 条返回。 我想自己封装,不使用其他包 以下为代码:

const axios = require('axios');
const cheerio = require('cheerio');
const url = require('url');

const href = 'https://cnodejs.org';

// 抓取url
axios.get(href)
      .then(res => {
        let $ = cheerio.load(res.data);
        let node = $('#topic_list a.topic_title');
        let list = [];
        node.each((index, value) => list.push(url.resolve(href, value.attribs.href)));
        return list;
      })
      .then(list => {
	  // 7 个并发
        many(list, 7).then(data => console.log(data)).catch(err => console.log(err));

      })
      .catch(err => err);


// 多线程异步,并发
function many (arr, n) {
  return new Promise((resolve, reject) => {
    // 多线程统一数据存放
    let list = [];
    // 正在运行的线程数
    let thread = 0;
    // 队列
    let length = 0;

    // 单线程异步
    function queues (arr) {
      return new Promise((resolve, reject) => {
        // 队列数据统一存放
        let datas = [];
        function queue (arr) {
          length ++;
          return new Promise((resolve, reject) => {
          axios.get(arr[length-1])
                .then(res => {
                  if (length < arr.length) {
                    console.log('...' + length);
                    datas.push(res.data);
                    return queue(arr).then(() => resolve());
                  }
                  else {
                    resolve();
                  }
      
      
                })
                .catch(err => reject(err));
          });
      
        }
      
        queue(arr).then(() => resolve(datas))
      });
    }

    // 多线程创建
    for (let i = 0; i < n; i ++) {
      thread++;
      queues(arr)
                .then(data => {
                  list.push(data);
                  thread--;
                  if (thread === 0) {
				  // 最后一个线程返回数据
                    resolve(list);
                  }
                })
                .catch(err => reject(err));
    }

  });
}

返回: image.png image.png

3 回复

解决了,折腾了一会,终于封装了一个控制异步并发的函数

恭喜恭喜。 刚开始学node,还没到多线程的部分呢。

@tingzhong666

终于封装了一个控制异步并发的函数

rxjs 控制并发很简单的。

回到顶部