- 前言
大家好,我是若川。为了能帮助到更多对源码感兴趣、想学会看源码、提升自己前端技术能力的同学。我倾力组织了每周大家一起学习200行左右的源码共读活动,感兴趣的可以点此扫码加我微信
ruochuan02
参与。
想学源码,极力推荐关注我写的专栏(目前1.9K人关注)《学习源码整体架构系列》 包含jQuery
、underscore
、lodash
、vuex
、sentry
、axios
、redux
、koa
、vue-devtools
、vuex4
、koa-compose
、vue 3.2 发布
、vue-this
、create-vue
、玩具vite
等20余篇源码文章。
本文仓库 https://github.com/lxchuan12/delay-analysis.git,求个star^_^
源码共读活动 每周一期,已进行到17期。于是搜寻各种值得我们学习,且代码行数不多的源码。delay 主文件仅70多行,非常值得我们学习。
阅读本文,你将学到:
1 | bash复制代码1. 学会如何实现一个比较完善的 delay 函数 |
- 环境准备
1 | bash复制代码# 推荐克隆我的项目,保证与文章同步 |
- delay
我们从零开始来实现一个比较完善的 delay 函数。
3.1 第一版 简版延迟
要完成这样一个延迟函数。
3.1.1 使用
1 | js复制代码(async() => { |
3.1.2 实现
用 Promise
和 setTimeout
结合实现,我们都很容易实现以下代码。
1 | js复制代码const delay1 = (ms) => { |
我们要传递结果。
3.2 第二版 传递 value 参数作为结果
3.2.1 使用
1 | js复制代码(async() => { |
我们也很容易实现如下代码。传递 value
最后作为结果返回。
3.2.2 实现
因此我们实现也很容易实现如下第二版。
1 | js复制代码const delay2 = (ms, { value } = {}) => { |
这样写,Promise
永远是成功。我们也需要失败。这时我们定义个参数 willResolve
来定义。
3.3 第三版 willResolve 参数决定成功还是失败。
3.3.1 使用
1 | js复制代码(async() => { |
3.3.2 实现
加个 willResolve
参数决定成功还是失败。于是我们有了如下实现。
1 | js复制代码const delay3 = (ms, {value, willResolve} = {}) => { |
3.4 第四版 一定时间范围内随机获得结果
延时器的毫秒数是写死的。我们希望能够在一定时间范围内随机获取到结果。
3.4.1 使用
1 | js复制代码(async() => { |
3.4.2 实现
我们把成功 delay
和失败 reject
封装成一个函数,随机 range
单独封装成一个函数。
1 | js复制代码const randomInteger = (minimum, maximum) => Math.floor((Math.random() * (maximum - minimum + 1)) + minimum); |
实现到这里,相对比较完善了。但我们可能有需要提前结束。
3.5 第五版 提前清除
3.5.1 使用
1 | js复制代码(async () => { |
3.5.2 实现
声明 settle
变量,封装 settle
函数,在调用 delayPromise.clear
时清除定时器。于是我们可以得到如下第五版的代码。
1 | js复制代码const randomInteger = (minimum, maximum) => Math.floor((Math.random() * (maximum - minimum + 1)) + minimum); |
3.6 第六版 取消功能
我们查阅资料可以知道有 AbortController 可以实现取消功能。
yet-another-abortcontroller-polyfill
3.6.1 使用
1 | js复制代码(async () => { |
3.6.2 实现
1 | js复制代码const randomInteger = (minimum, maximum) => Math.floor((Math.random() * (maximum - minimum + 1)) + minimum); |
3.7 第七版 自定义 clearTimeout 和 setTimeout 函数
3.7.1 使用
1 | js复制代码const customDelay = delay7.createWithTimers({clearTimeout, setTimeout}); |
3.7.2 实现
传递 clearTimeout, setTimeout 两个参数替代上一版本的clearTimeout,setTimeout
。于是有了第七版。这也就是delay的最终实现。
1 | js复制代码const randomInteger = (minimum, maximum) => Math.floor((Math.random() * (maximum - minimum + 1)) + minimum); |
- axios 取消请求
axios
取消原理是:通过传递 config
配置 cancelToken
的形式,来取消的。判断有传cancelToken
,在 promise
链式调用的 dispatchRequest
抛出错误,在 adapter
中 request.abort()
取消请求,使 promise
走向 rejected
,被用户捕获取消信息。
更多查看我的 axios
源码文章取消模块 学习 axios 源码整体架构,取消模块
- 总结
我们从零开始实现了一个带取消功能比较完善的延迟函数。也就是 delay 70多行源码的实现。
包含支持随机时间结束、提前清除、取消、自定义 clearTimeout、setTimeout
等功能。
取消使用了 mdn AbortController ,由于兼容性不太好,社区也有了相应的 npm abort-controller 实现 polyfill
。
yet-another-abortcontroller-polyfill
建议克隆项目启动服务调试例子,印象会更加深刻。
1 | bash复制代码# 推荐克隆我的项目,保证与文章同步 |
最后可以持续关注我@若川。我倾力持续组织了一年每周大家一起学习200行左右的源码共读活动,感兴趣的可以点此扫码加我微信 ruochuan02
参与。
另外,想学源码,极力推荐关注我写的专栏《学习源码整体架构系列》,目前是掘金关注人数(4.2k+人)第一的专栏,写有20余篇源码文章。包含jQuery
、underscore
、lodash
、vuex
、sentry
、axios
、redux
、koa
、vue-devtools
、vuex4
、koa-compose
、vue 3.2 发布
、vue-this
、create-vue
、玩具vite
、create-vite
等20余篇源码文章。
关于 && 源码共读交流群
作者:常以若川为名混迹于江湖。欢迎加我微信ruochuan02
。前端路上 | 所知甚少,唯善学。
关注公众号若川视野,每周一起学源码,学会看源码,进阶高级前端。
segmentfault
若川视野专栏,开通了若川视野专栏,欢迎关注~
掘金专栏,欢迎关注~
知乎若川视野专栏,开通了若川视野专栏,欢迎关注~
github blog,求个star
^_^~
本文转载自: 掘金