nodejs 模拟多线程遇到的一个问题
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
.