多次请求订单数据再存入数据库的思路:https://ourcoders.com/thread/show/7909/
控制并发的方法原文:https://segmentfault.com/a/1190000016389127?utm_source=tag-newest
思路
- 先给平台发一个请求,获得 count
- 根据 count 和我的 pageSize 来判定需要多少个请求
- 组装所有的请求,合并成一个 Array
- 使用 Promise.all(Array) 来进行处理
- 最后对结果数据进行下处理,然后同步到数据库
- 这时候考虑一个场景:如果你的promises数组中每个对象都是http请求,或者说每个对象包含了复杂的调用处理。而这样的对象有几十万个。那么会出现的情况是,你在瞬间发出几十万http请求(tcp连接数不足可能造成等待),或者堆积了无数调用栈导致内存溢出。这时候,我们就需要考虑对Promise.all做并发限制。
核心代码
const asyncPool = (poolLimit, array, iteratorFn) => {
let i = 0;
const ret = [];
const executing = [];
const enqueue = function () {
// 边界处理,array为空数组
if (i === array.length) {
return Promise.resolve();
}
// 每调一次enqueue,初始化一个promise
const item = array[i++];
const p = Promise.resolve().then(() => iteratorFn(item, array));
// 放入promises数组
ret.push(p);
// promise执行完毕,从executing数组中删除
const e = p.then(() => executing.splice(executing.indexOf(e), 1));
// 插入executing数字,表示正在执行的promise
executing.push(e);
// 使用Promise.rece,每当executing数组中promise数量低于poolLimit,就实例化新的promise并执行
let r = Promise.resolve();
if (executing.length >= poolLimit) {
r = Promise.race(executing);
}
// 递归,直到遍历完array
return r.then(() => enqueue());
};
return enqueue().then(() => Promise.all(ret));
}
页码page字段计算函数,用数组形式传入
// 并发请求中,多次请求的参数用数组传入,此处只有pge加1,其他参数不变,所以用该方法生成page的数组
const generateArray = (start, end) => {
return Array.from(new Array(end + 1).keys()).slice(start)
}
调用
const times = Math.ceil(total / SIZE); // 需要查询的次数、一共查询多少页
const reqFun = async i => {
params.page = i;
const result = await request(url, params, opts);
return result.msg.records; // records是第三方的list参数
};
return asyncPool(CONCURRENT_COUNT, generateArray(1, times), reqFun).then(resp => {
for (let r = 0; r < resp.length; r++) {
const o = resp[r];
list = list.concat(o);
}
// 将list存入数据库
});