事情是这样的
20多年的日积月累,20多年的母胎单身,20多年一次次的沉淀,咸鱼总会翻身的,我一直告诉着自己,是金子总会发光的,我时常这样子告诫自己。
我忍了这么久,这不机会就来了嘛!
今天如往常般,带着修行的心态上班,为什么上班要带着修行的心,因为上班就是为了修福报------周树人
这都不是关键。
关键的是,当我刚刚坐到工位上的时候,我的微信响了,竟然是我的女神找我了。
当我用颤抖的手点开微信之后,我瞬间炸裂了。
啊?昨晚卡住了?一瞬间我脑海里幻想了出了各种画面,什么卡住了,什么东西晚上卡住,莫非是......
打住!我女神这么冰清玉洁,绝对不是我想的那种,到底是什么卡住了,经过我一番询问和调查之后,原来是女神昨晚用公司的某个系统的时候,有一个功能卡住了。
经过我的长达多个小时的调试之后发现,原来是有个功能在一瞬间调用了多个请求,导致页面卡住了,既然这样为了让女神不再难受,那就把这个问题解决掉。
说干就干
既然一次性请求太多导致卡顿,那我就控制一下就好了。
思路:写一个队列,每次请求队列的前几个,等结果成功后再继续请求,直到队列为空
整个大致的思路过程就是这样子。
没看懂?那来看看代码。
// 成功队列
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
函数每次获取一个任务,然后执行,当任务执行完之后检测任务队列中是否还有任务,有就重复执行。
怎么样,是不是很简单,那么问题来了,如果任务有报错那怎么解决呢?
其实报错很简单,只需要知道他是报错就好了(你看看你到底在说什么.jpg)。
思路: 如果任务报错,记录任务报错次数,然后重新进入队列,如果报错次数超过一定次数,返回reject
还是不懂?看代码。
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
回任务队列,然后继续执行任务。
整个异步并发控制的函数到这里基本完成了,我立马给小姐姐安排上。
一些功能上的拓展
整个功能函数只是简单做了一个队列的并发控制,还要结合产品中的需求进行调整,例如一些错误信息记录什么的,一大堆都可以搞,这里只讲思路和简单实现。
最后结局
我产品的功能优化完毕之后,我就和女神小姐姐去领工了。
当然多年的沉淀和等待,不只是锻炼了我写代码的能力,更是锻炼了我把握机会的意识。
这次,就是机会,吹响进攻的号角~~~
直接一个微信发过去,“嗨,生孩子”。
结果!!!
就这样吧,我还是继续潜心的修行吧。
唉,其实人嘛,开心点就好,单不单身无所谓-----鲁迅。