带你手写promise (上)

357 阅读3分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

Promise项目构建

  • self-promise 文件夹
    • lib 存放js文件

      • promise.js 函数
    • index.html 测试promise

  • promise.js 函数 基础构建 (ES5语法)
// 自定义promise函数 模块

(function (window) {
    /*
        Promise 构造函数
        excutor 执行器函数(同步)
    */
    function Promise(excutor) {


    }
    /*
        Promise原型上的then方法 
        指定成功和失败的回调函数
        返回一个新的promise对象
     */
    Promise.prototype.then = function (onResolved, onRjected) {

    }

    /*
        Promise原型上的catch方法 
        指定失败的回调函数
        返回一个新的promise对象
     */
    Promise.prototype.catch = function (onRjected) {

    }

    /*
        Promise函数对象的resolve方法
        返回一个指定value的成功promise
    */

    Promise.resolve = function (value) {

    }

    /*
        Promise函数对象的reject方法
        返回一个指定reason的失败promise
    */

    Promise.reject = function (reson) {

    }

    /*
        Promise函数对象的all方法
        返回一个promise,只有当所有promise都成功时,否则失败
    */

    Promise.all = function (promises) {

    }

    /*
        Promise函数对象的race方法
        返回一个promise,结果由第一个完成的promise决定
    */

    Promise.race = function (promises) {

    }
    

    // 向外暴露Promise函数
    window.Promise = Promise
})(window)

Promise 函数

    //  定义常量 
    const PENDING = 'pending'
    const RESOLVED = 'resolved'
    const REJECTED = 'rejected'

    function Promise(excutor) {
        // 将当前promise保存起来
        const _that = this
        _that.status = PENDING // 给promise对象指定status属性, 初始值为pending
        _that.data = undefined // 给promise对象指定一个用于存储结果数据的属性
        _that.callbacks = []    // 每个元素的结构 {onResolved() {}, onRejected() {}}
        function resolve(value) {
            // 如果当前状态不是pending 直接结束
            if (_that.status !== PENDING) {
                return
            }
            // 将状态改为resolved
            _that.status = RESOLVED
            //保存value数据
            _that.data = value
            // 如果有待执行的callbacks函数, 立即异步执行回调函数
            if (_that.callbacks.length > 0) {
                setTimeout(() => { // 放入队列中执行所有成功的回调
                    _that.callbacks.forEach(callbacksObj => {
                        callbacksObj.onResolved(value)
                    });
                })

            }
        }

        function reject(reason) {
            // 如果当前状态不是pending 直接结束
            if (_that.status !== PENDING) {
                return
            }
            // 将状态改为reject
            _that.status = REJECTED
            //保存value数据
            _that.data = reason
            // 如果有待执行的callbacks函数, 立即异步执行回调函数
            if (_that.callbacks.length > 0) {
                setTimeout(() => { // 放入队列中执行所有失败的回调
                    _that.callbacks.forEach(callbacksObj => {
                        callbacksObj.onRjected(reason)
                    });
                })

            }
        }

        // 立即同步执行 执行器 内部调用 resolve reject
        // 如果发生异常 直接触发失败
        try {
            excutor(resolve, reject)
        } catch (error) {
            reject(error)
        }


    }

Promise.then方法

    Promise.prototype.then = function (onResolved, onRjected) {
        onResolved = typeof onResolved === 'function' ? onResolved : value => value
        // 指定默认的失败回调  实现错误、异常穿透的关键
        onRjected = typeof onRjected === 'function' ? onRjected : reason => { throw reason }
        const _that = this
        // 返回一个新的promise
        return new Promise((resolve, reject) => {

            /*
                调用指定函数处理 根据执行的结果改变return的promise状态
            */
            function handle(callback) {
                /*
                   1. 如果执行抛出异常,return的promise就会失败,reason就是error
                   2. 如果回调函数执行返回非promise,return的promise就会成功,value就是返回的值
                   3. 如果回调函数执行返回是promise,return的promise就是这个promise的结果
                   */
                try {
                    const result = callback(_that.data)
                    //    3. 如果回调函数执行返回是promise,return的promise就是这个promise的结果
                    if (result instanceof Promise) {
                        // 基础语法
                        // result.then(
                        //     value =>resolve(value), // result 成功时,让return的promise也成功
                        //     reason =>reject(reason) // result 失败时,让return的promise也失败
                        // )
                        // 简洁语法
                        result.then(resolve, reject)
                    } else {
                        //    2. 如果回调函数执行返回非promise,return的promise就会成功,value就是返回的值
                        resolve(result)
                    }
                    // 1. 如果执行抛出异常,return的promise就会失败,reason就是error
                } catch (error) {
                    reject(error)
                }
            }
            // 当前状态是pending 将回调函数保存起来
            if (_that.status == PENDING) {
                _that.callbacks.push({
                    onResolved(value) {
                        handle(onResolved)
                    },
                    onRjected(reason) {
                        handle(onRjected)
                    }
                })
            } else if (_that.status = RESOLVED) { // 如果当前是resolve状态,异步执行onResolved并改变promise状态
                setTimeout(() => {
                    handle(onResolved)
                })
            } else { //'rejected'
                setTimeout(() => { // 如果当前是rejected状态,异步执行onRejected并改变promise状态
                    handle(onRjected)
                })
            }
        })
    }

Promise.catch

    //直接返回错误即可
    Promise.prototype.catch = function (onRjected) {
        return this.then(undefined, onRjected)
    }

总结

  • 今天手写了Promise函数及then和catch方法 剩余的明天再更
  • class版本明天改写..... 敬请期待