讲解在同名B/D上都有,主要介绍一些跟业务无关的代码技巧
注: 部分内容主观性较大,一家之言姑且听之
本文主要介绍setInterval
的二次封装
原文
这是项目中的某个封装,目的是处理,正在请求的问题,如使用中的描述
设置定时器1s执行,但如果1s时,请求没有完成,则忽略当前请求,代码可以实现,但可以优化下
function Timer() {
this.flag = true
this.setTime = (time, callback) => {
this.clearTime = setInterval(() => {
if (this.flag) {
if (callback) callback()
}
}, time * 1000)
}
}
const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms))
let t = Date.now()
// ... 使用
const timer = new Timer()
timer.setTime(1, async function () {
timer.flag = false
await sleep(2500)
timer.flag = true
console.log(Date.now() - t)
t = Date.now()
})
setTimeout与setInterval
涉及一点这两个的区别,尤其是setInterval
的调度问题
- 长任务会爆栈吗?
setInterval
是宏任务,假设定时1s执行1次,但里面的任务是长任务,1.1s才能执行完,此时,会出现宏任务无法退出的问题吗?
不会,如果定时器到了,但对应的任务没有执行完,这次注入会取消,但只限于长任务,对异步任务无效,也就是长任务与异步任务会有区别
解决方案,让两种任务表现一致
间隔方式如下如,这就是使用setTimeout代替setInterval
间隔1s | 执行时间 | 间隔1s | 执行时间 | 间隔1s
function setInterval1(promiseFn,time){
setTimeout(async () => {
// 需要判断是否为异步函数,省些
await promiseFn()
setInterval1(promiseFn,time)
},time)
}
setInterval1(async function(){
await sleep(2500)
console.log(Date.now() - t)
t = Date.now()
},1000)
其他可以添加的内容
- 次数,setInterval1 需要决定可以请求几次
- abort,整个响应可以取消
- 时间可以为函数,描述随机时间
- ...