nodejs 模拟多线程遇到的一个问题
发布于 5 年前 作者 UoToGK 3142 次浏览 来自 问答
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));
        }
    });
}
//我要怎么 打出0-7之间
2 回复

多线程异步你是真的有点作啊~

之前朋友搞过爬虫,单线程,在 单核1G 100M 带宽(日本)的机器上,CPU 在30-80% 之间,100M带宽首先不够用了。

爬虫不做大量的数据处理的话,就是高IO密集型的应用,请关掉多线程 以提高性能【避免不必要的线程切换和线程通信】。同时降低了复杂度~

楼主你对node的单线程和异步I/O是不是有所误会?

libuv实现异步I/O靠的就是I/O多路复用+线程池(多线程),也就是咱常说的事件循环,你这只是在控制异步IO的并发数,js代码执行该单线程还是单线程,类似Async.parallelLimit.

回到顶部