Promise学习笔记-一

Promise基本概念

Promise含义

Promise是异步编程的一种解决方案。简单说就是一个容器,里面保存着某个未来才会结束的事件的结果。从语法上讲,Promise是一个对象,从它可以获取异步操作的消息。

Promise的原理

Promise提供一个包裹异步操作处理的容器,容器通过三个不同状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)输出处理程序的结果,通过then或catch方法接收异步处理操作的结果并对结果做相应处理。then方法的链式调用避免了传统函数回调嵌套,增强了代码的可读性。

Promise的特点

  1. Promise对象的状态不受外界影响。Promise有三种状态:pending(运行中)、fulfilled(已成功)、rejected(已失败)。只有异步操作的结果可以决定当前是哪种状态,任何其他操作都无法改变这个状态
  2. 一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变只有两种可能:从pending到fulfilled和从pending到rejected。只要这两种情况发生,状态就不会再变,称为定型(resolved)

Promise的缺点

  1. 无法取消,一旦新建它就会立即执行,中途无法取消
  2. 如果不设置回调函数,Promise内部抛出的错误无法反应到外部
  3. 当处于pending状态时,无法的得知目前进行到哪一个阶段

Promise的简单实现

  • 定义MyPromise类。定义MyPromise中自身属性及绑定

    class MyPromise {
        constructor (fn) {
            const that = this
            that._value = 0
        }
    }
    复制代码
  • 在MyPromise实例化时,需要传入一个函数作为参数,函数有需要resolve和reject函数作为参数。实现方法如下:

    function tryCallTwo (fn, a, b) {
        try {
            fn (a, b)
        } catch (e) {
            return e
        }
    }
    复制代码

    将此方法在MyPromise类的内部调用,完成传入fn函数的绑定。

    class MyPromise {
        constructor (fn) {
            const that = this
            that._value = 0
            tryCallTwo (fn, function (value) {
                console.log(value) // 2
            }, function (err) {
                console.log(err)
            })
        }
    }
    
    new MyPromise(function (resolve, reject) {
        resolve(2)
    })
    复制代码

    通过tryCallTwo方法将实例化时传入的函数的resolve或reject转化为处理函数;通过以上打印可知tryCallTwo方法的第二个参数就是实例化时传入的resolve的处理函数。在MyPromise类中tryCallTwo方法中的第二个参数内部,调用resolve方法,作为处理函数。MyPromise类修改如下:

    class MyPromise {
        constructor (fn) {
            const that = this
            that._value = 0
            tryCallTwo (fn, function (value) {
                console.log(value) // 2
                resolve(that, value)
            }, function (err) {
                console.log(err)
            })
        }
    }
    复制代码
  • 定义resolve方法,此方法需要传入当前的实例作为第一个参数,实例化时resolve(2)传入的值作为第二个参数。在resolve方法中相当于修改MyPromise类中_value的值

    function resolve (self, newValue) {
        self._value = newValue
    }
    复制代码
  • 到此为止MyPromise的输出已经解决,接下来定义接收处理方法then。由于then是实例方法,所以要定义在MyPromise类的内部

    class MyPromise {
        constructor (fn) {...}
        then (onFulfilled) {
            // 判断then传入的参数是否是function
            let cb = typeof onFulfilled === 'function' ? onFulfilled : null
            // 如果cb存在为其添加处理过程
            cb && tryCallOne(cb, that._value)
        }
    }
    复制代码
  • 定义tryCallOne方法

    tryCallOne (fn, a) {
        try {
            return fn (a)
        } catch (e) {
            return e
        }
    }
    复制代码
  • 通过实例调用then方法

    new MyPromise(function (resolve, reject) {
        resolve(3)
    }).then(res => {
        console.log(res) // 3
    })
    复制代码

完整代码

// 实现MyPromise构造函数两个函数参数的绑定
function tryCallTow (fn, a, b) {
    try {
        fn(a, b)
    } catch (ex) {
        return ex
    }
}
// 实现then方法中函数参数传入
function tryCallOne (fn, a) {
    try {
        return fn(a)
    } catch (ex) {
        return ex
    }
}
// resolve方法
function resolve (self, newValue) {
    self._value = newValue
}
// noop方法:在resolve传入简单数据类型值时作为参数传给
class MyPromise {
    constructor(fn) {
        const that = this
        this._value = 0
        tryCallTow(fn, function (value) {
            resolve(that, value)
        }, function (err) {
            console.log(err)
        })
    }
    then (onFulfilled) {
        let cb = typeof onFulfilled === 'function' ? onFulfilled : null
        cb && tryCallOne(cb, this._value)
    }
}
复制代码

完整的运行流程

MyPromise运行流程.gif

参考文献

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享