多次请求订单数据再存入数据库的思路: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,初始化一个promiseconst 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数字,表示正在执行的promiseexecuting.push(e);// 使用Promise.rece,每当executing数组中promise数量低于poolLimit,就实例化新的promise并执行let r = Promise.resolve();if (executing.length >= poolLimit) {r = Promise.race(executing);}// 递归,直到遍历完arrayreturn 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存入数据库});
