前言
作为一个后端过来的同学, 刚入门前端的时候, 被 js 种种反人类的概念折腾的死去活来的.
其中一个印象比较深刻的, 就是 promise, 感觉实在太难理解了... 所有就有了写个简单的 promise 的想法.
希望能帮助到一些跟我一样, 感觉 promise 很难理解的新同学.
promise 的教程网上多如牛毛, 其中写的比较通俗易懂的莫过于阮一峰的 es6, 反正我是他的书才懂的.
所以今天, 我们也不会来复述一遍如何使用 promise, 今天我们从另一个角度学习 promise,
先自己动手造一个轮子 -- 实现一个最简单的 promise, 解决 回调地狱 的问题.
简单实现
请看代码
- function easyPromise (fn) {
- this.then = cb => this.cb = cb
- this.resolve = data => this.cb(data)
- fn(this.resolve)
- }
详解
上面的代码就实现了一个简单的, 实现 then 回调的promise, 这里为了缩短代码量, 用了 es6 的简写, 实际展开应该是这样
- function easyPromise (fn) {
- var that = this
- // 第一步, 定义 then()
- this.then = function (cb) {
- // 先将 then() 括号里面的参数 (回调函数) 保存起来
- that.cb = cb
- }
- // 定义一个 resolve
- this.resolve = function(data) {
- that.cb(data)
- }
- // 将 resolve 作为回调函数, 传给 fn
- fn(this.resolve)
- }
接下来我们看看如何使用
- new easyPromise((resolve) => {
- setTimeout(() => {
- resolve("延时执行")
- }, 1000)
- }).then((data) => {
- console.log(data)
- })
结果: 控制台在 1 秒之后, 输出 延时执行
同样为了方便理解, 我们不妨把以上代码写好理解一点.
- // 定义一个要传给 promise 的函数, 它接收一个函数 (resolve) 作为参数.
- // resolve 的作用是在合适的时间, 通知 promise 应该要执行 then 里面的回调函数了.
- function promiseCallback (resolve) {
- setTimeout(() => {
- resolve("延时执行")
- }, 1000)
- }
- // 定义一个 要传给 then 的回调函数
- function thenCallback (data) {
- console.log(data)
- }
- // 实例化 promis, 并分别传入对应的回调
- new easyPromise(promiseCallback)
- .then(thenCallback)
tips: promise.then() 的时候, 并没有马上执行括号里面的回调函数, 只是把括号里面的回调函数保存起来.
我们来梳理一下执行流程
先通过 then 把 thenCallback 存起来
- this.then = function (cb) {
- that.cb = cb
- }
这里的 cb , 就是上例的 thenCallback 所以其实可以等价于
this.cb = thenCallback
执行 promise 括号里的函数, 并把事先定义好的 resolve 函数作为参数传给他
fn(this.resolve)
这里的 fn , 就是上例的 promiseCallback
执行 promiseCallback 我们的逻辑就跳到 promiseCallback 函数内部去
- setTimeout(() => {
- resolve("延时执行")
- }, 1000)
逻辑很简单, 就是等待 1 秒后, 执行 resolve 函数, 这个 resolve 哪来的呢?
- fn(this.resolve) ->
- promiseCallback (resolve)
- -> resolve
执行 resolve 我们的逻辑就跳到 resolve 函数内部去
that.cb(data)
这个 that.cb 又是哪来的呢? 就是我们第一步保存的 then 括号里面的回调函数, 也就是 thenCallback
console.log(data)
所以就在 1 秒后输出 延时执行
来源: https://www.cnblogs.com/noahnee/p/9103425.html