var http = require("http")
const moment = require('moment');
function asyncPools(factory, maxRun /*并发最大数量*/ , intiArray = [] /*初始化任务列表*/ , startIndex = 0, executing = [] /*运行中*/ ) {
let results = []; // 结果集
intiArray = Array.from(new Set(intiArray)); // set方法数组去重
function promiseMax() {
// 最后一个resolve状态,会进入外层返回Promise.then
if (startIndex >= intiArray.length) return Promise.resolve();
let mi = intiArray[startIndex++]
let pro = factory(mi); // 当前任务对象
if (pro instanceof Promise) {
pro.then(() => {
executing.splice(executing.indexOf(pro), 1);
}).catch(err => err)
executing.push(pro);
results.push(pro);
}
// 监听每完成一个就再放一个
if (executing.length >= maxRun) {
// race: 哪个 Promise 对象最快得到结果,就返回那个结果,不管结果本身是成功状态还是失败状态。
return Promise.race(executing).then(promiseMax);
} else {
// 改写一下保证then链式调用
return Promise.resolve().then(promiseMax);
}
}
// 注意:这不管是all还是allSettled,子任务失败时都会返回【主要是race函数的作用】
return promiseMax().then(() => Promise.all(results));
}
let maxRun = 5;
let intiArray = [1000, 5000, 3000, 2000, 7000, 1000, 5000, 3000, 2000, 1000];
/*模拟函数: 这里模拟延迟操作*/
const timeout = i => new Promise((resolve, reject) => {
setTimeout(() => {
// 自定义错误提醒
if (i === 3000) {
// console.log(param, ' failed')
return reject({
status: 'error',
data: i,
date: moment(new Date()).format('YYYY-MM-DD HH:mm:ss')
})
}
console.log(i);
// 正常通过的数据
resolve({
status: 'success',
data: 200,
date: moment(new Date()).format('YYYY-MM-DD HH:mm:ss')
});
}, i)
}).catch(err => err);
// 测试并发请求
// asyncPools(timeout, maxRun, intiArray).then(res => {
// console.log(res)
// }).catch(err => {
// throw Error(err)
// }).finally(() => {
// console.log('结束...')
// });
// https://blog.csdn.net/qq_35425276/article/details/80002812
let videoIds = [348, 259, 197, 134, 75, 348]
const baseUrl = 'http://www.imooc.com/learn/'
const getPageAsync = (id) => new Promise((resolve, reject) => {
var url = baseUrl + id;
console.log('正在爬取 ' + url);
http.get(url, function(res) {
var html = '';
// $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
res.on('data', function(data) {
html += data.toString('utf-8');
})
// $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
res.on('end', function() {
// 把当前的获取到页面的html返回回去(传递下去)
resolve({
status: 'success',
data: html,
date: moment(new Date()).format('YYYY-MM-DD HH:mm:ss')
});
})
}).on('error', function(e) {
console.log("获取课程数据出错!");
return reject({
status: 'error',
data: e,
date: moment(new Date()).format('YYYY-MM-DD HH:mm:ss')
})
})
}).catch(err => err);
// 测试并发请求
asyncPools(getPageAsync, 2, videoIds).then(pages => {
// console.log(pages)
// 页面解析
// let coursesData = []
// pages.forEach(function(html) {
// let courses = filterChapters(html)
// coursesData.push(courses)
// })
// 排序
// coursesData.sort(function(a, b) {
// return a.number < b.number
// })
}).catch(err => {
throw Error(err)
}).finally(() => {
console.log('结束...')
});
【2021-08-20】测试Promise爬虫示例
最新推荐文章于 2022-03-04 12:10:46 发布