【JS高级异步并发】我使出了浑身解数只为帮小姐姐解决问题,结果......😭

556 阅读3分钟

事情是这样的

20多年的日积月累,20多年的母胎单身,20多年一次次的沉淀,咸鱼总会翻身的,我一直告诉着自己,是金子总会发光的,我时常这样子告诫自己。

我忍了这么久,这不机会就来了嘛!

今天如往常般,带着修行的心态上班,为什么上班要带着修行的心,因为上班就是为了修福报------周树人

苏大强00014-我就要钱.gif

这都不是关键。

关键的是,当我刚刚坐到工位上的时候,我的微信响了,竟然是我的女神找我了。

当我用颤抖的手点开微信之后,我瞬间炸裂了。

image.png

啊?昨晚卡住了?一瞬间我脑海里幻想了出了各种画面,什么卡住了,什么东西晚上卡住,莫非是......

打住!我女神这么冰清玉洁,绝对不是我想的那种,到底是什么卡住了,经过我一番询问和调查之后,原来是女神昨晚用公司的某个系统的时候,有一个功能卡住了。

苏大强00008-不敢吱声.gif

经过我的长达多个小时的调试之后发现,原来是有个功能在一瞬间调用了多个请求,导致页面卡住了,既然这样为了让女神不再难受,那就把这个问题解决掉。

说干就干

既然一次性请求太多导致卡顿,那我就控制一下就好了。

思路:写一个队列,每次请求队列的前几个,等结果成功后再继续请求,直到队列为空

image.png

整个大致的思路过程就是这样子。

没看懂?那来看看代码。


   // 成功队列
   const result = []
   // limit 4 即每次控制在4个任务数量
   const handle = (tasks, limit = 4) => {
       // 返回一个promise
       return new Promise((resolve, reject) => {
           // 记录任务次数
           let count = 0
           
           const start = () => {
               // 获得一个任务 每个任务是promise
               const task = tasks.shift()
               
               task.then(res => {
                   result.push(res)
                   if (count === tasks.length - 1) {
                       resolve()
                   } else {
                       count++
                       start()
                   }
               })
           }
           // 开始执行 执行4次就是每次四个任务
           while (limit > 0) {
              start()
              limit -= 1
            }
       })
   }
   

代码中主要逻辑是通过start函数每次获取一个任务,然后执行,当任务执行完之后检测任务队列中是否还有任务,有就重复执行。

怎么样,是不是很简单,那么问题来了,如果任务有报错那怎么解决呢?

奇妙猫00001-宇宙数学猫.jpg

其实报错很简单,只需要知道他是报错就好了(你看看你到底在说什么.jpg)。

思路: 如果任务报错,记录任务报错次数,然后重新进入队列,如果报错次数超过一定次数,返回reject

image.png

还是不懂?看代码。

      const handle = (tasks, limit = 4) => {
       // 返回一个promise
       return new Promise((resolve, reject) => {
           // 记录任务次数
           let count = 0
           let stopFlag = false
           const start = () => {
               if (stopFlag) return
               // 获得一个任务 每个任务是promise
               const task = tasks.unshift()
               task.error = 0
               task.then(res => {
                   // do something
               }).catch(e => {
                   // 判断错误次数
                   if (task.error < 3) {
                       // 次数+1 重新入队列 继续start
                       task.error++
                       tasks.unshift(task)
                       start()
                   } else {
                       // 有任务错误次数超过3次 中止任务
                       stopFlag = true
                       reject(e)
                   }
               })
           }
           // 开始执行
           while (limit > 0) {
              start()
              limit -= 1
            }
       })
   }

就是在刚刚的handle函数中,给每个任务添加一个标识属性记录错误次数,当任务的执行错误的时候标识属性+1之后unshift回任务队列,然后继续执行任务。

ca78b54fadce4c12ade4fbd46d67e412_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.webp

整个异步并发控制的函数到这里基本完成了,我立马给小姐姐安排上。

一些功能上的拓展

整个功能函数只是简单做了一个队列的并发控制,还要结合产品中的需求进行调整,例如一些错误信息记录什么的,一大堆都可以搞,这里只讲思路和简单实现。

狗00018-微笑.jpg

最后结局

我产品的功能优化完毕之后,我就和女神小姐姐去领工了。

当然多年的沉淀和等待,不只是锻炼了我写代码的能力,更是锻炼了我把握机会的意识。

胖虎00001-意气风发.gif

这次,就是机会,吹响进攻的号角~~~

直接一个微信发过去,“嗨,生孩子”。

结果!!!

image.png

就这样吧,我还是继续潜心的修行吧。

唉,其实人嘛,开心点就好,单不单身无所谓-----鲁迅。

1551949742389822.jpg