promise处理并发请求

阳光穿透心脏的1/2处 2022-12-01 01:23 232阅读 0赞
  1. asyncPool=(poolLimit, array, iteratorFn)=> {
  2. let i = 0;
  3. const ret = [];
  4. const executing = []
  5. const enqueue = function () {
  6. // 边界处理,array为空数组
  7. if (i === array.length) {
  8. return Promise.resolve();
  9. }
  10. // 每调一次enqueue,初始化一个promise
  11. const item = array[i++];
  12. const p = Promise.resolve().then(() => iteratorFn(item, array));
  13. // 放入promises数组
  14. ret.push(p);
  15. // promise执行完毕,从executing数组中删除
  16. const e = p.then(() => executing.splice(executing.indexOf(e), 1));
  17. // 插入executing数字,表示正在执行的promise
  18. executing.push(e);
  19. // 使用Promise.rece,每当executing数组中promise数量低于poolLimit,就实例化新的promise并执行
  20. let r = Promise.resolve();
  21. if (executing.length >= poolLimit) {
  22. r = Promise.race(executing);
  23. }
  24. // 递归,直到遍历完array
  25. return r.then(() => enqueue());
  26. };
  27. return enqueue().then(() => Promise.all(ret));
  28. }

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5ODk3OTc4_size_16_color_FFFFFF_t_70

  1. /** * @params list {Array} - 要迭代的数组 * @params limit {Number} - 并发数量控制数 * @params asyncHandle {Function} - 对`list`的每一个项的处理函数,参数为当前处理项,必须 return 一个Promise来确定是否继续进行迭代 * @return {Promise} - 返回一个 Promise 值来确认所有数据是否迭代完成 */
  2. let mapLimit = (list, limit, asyncHandle) => {
  3. let recursion = (arr) => {
  4. return asyncHandle(arr.shift())
  5. .then(()=>{
  6. if (arr.length!==0) return recursion(arr) // 数组还未迭代完,递归继续进行迭代
  7. else return 'finish';
  8. })
  9. };
  10. let listCopy = [].concat(list);
  11. let asyncList = []; // 正在进行的所有并发异步操作
  12. while(limit--) {
  13. asyncList.push( recursion(listCopy) );
  14. }
  15. return Promise.all(asyncList); // 所有并发异步操作都完成后,本次并发控制迭代完成
  16. }

第三种的方式

  1. //省略代码
  2. // 计数器
  3. var count = 0;
  4. // 全局锁
  5. var lock = [];
  6. var l = urls.length;
  7. // 阻塞函数
  8. function block(){
  9. let _resolve;
  10. return new Promise((resolve,reject)=>{
  11. _resolve=resolve;
  12. // resolve不执行,将其推入lock数组;
  13. lock.push(_resolve);
  14. });
  15. }
  16. // 叫号机
  17. function next(){
  18. lock.length&&lock.shift()()
  19. }
  20. async function bao(){
  21. if(count>=3){
  22. //超过限制利用await和promise进行阻塞;
  23. await block();
  24. }
  25. if(urls.length>0){
  26. console.log(count);
  27. count++
  28. await loadImg(urls.shift());
  29. count--;
  30. next()
  31. }
  32. }
  33. for (let i = 0; i < l; i++) {
  34. bao();
  35. }

发表评论

表情:
评论列表 (有 0 条评论,232人围观)

还没有评论,来说两句吧...

相关阅读

    相关 promise并发

    一、Pomise.all的使用 Promise.all可以将多个Promise实例包装成一个新的Promise实例。同时,成功和失败的返回值是不同的,成功的时候返回的是一个结

    相关 Promise并发做异步请求

    并发做异步请求,限制频率 1. 举个例子,有 8 张图片 url,你需要并发去获取它,并且任何时刻同时请求的数量不超过 3 个。也就是说第 4 张图片一定是等前面那一批

    相关 android并发请求处理

    最近在做android统计SDK,因为之前参与的网络开发项目都遇到一些相同的问题: 1.大量的并发请求造成堵塞,特别是遇上让人无语的3G网络,无限loading。。。 2.