A-A+

仿写promise源码

2018年10月04日 JavaScript 暂无评论 阅读 46 次

promise源码

最核心的功能

let promise = new MyPromise((resolve, reject) => {
    setTimeout(() => {
        resolve('result')
        console.log()
    }, 1000)
})

console.log(promise)//MyPromise {_status: "PENDING", _value: undefined}

setTimeout(function () {
    console.log(promise)
},3000) //MyPromise {_status: "FULFILLED", _value: "result"}

实现代码

//定义三种状态 promise 有三种状态:  发送中 成功 失败

// 定义Promise的三种状态常量
const PENDING = 'PENDING'
const FULFILLED = 'FULFILLED'
const REJECTED = 'REJECTED'

class MyPromise {
    constructor (handle) {
        // if (!isFunction(handle)) {
        //     throw new Error('MyPromise must accept a function as a parameter')
        // }
        // 添加状态
        this._status = PENDING
        // 添加状态
        this._value = undefined
        // 执行handle
        try {
            handle(this._resolve.bind(this), this._reject.bind(this))
        } catch (err) {
            this._reject(err)
        }
    }
    // 添加resovle时执行的函数
    _resolve (val) {
        if (this._status !== PENDING) return
        this._status = FULFILLED
        this._value = val
    }
    // 添加reject时执行的函数
    _reject (err) {
        if (this._status !== PENDING) return
        this._status = REJECTED
        this._value = err
    }
}

最终版本

仿写promise源码

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<!--<script src="error.js"></script>-->
<script src="tPromise.js"></script>
<script>
    let promise = new MyPromise((resolve, reject) => {
        setTimeout(() => {
            console.log("chenggong!");
            resolve(111)
        }, 1000)
    })

    console.log(2222)

    promise.then(data => {
        console.log(44444)
        console.log(data)
    })
</script>
</body>
</html>

promise.js

//定义三种状态 promise 有三种状态:  发送中 成功 失败
// 判断变量否为function
const isFunction = variable => typeof variable === 'function'
// 定义Promise的三种状态常量
const PENDING = 'PENDING'
const FULFILLED = 'FULFILLED'
const REJECTED = 'REJECTED'

class MyPromise {
    // 接受一个参数,为函数,该函数会有两个参数
    constructor (handle) {
        if (!isFunction(handle)) {
            throw new Error('MyPromise must accept a function as a parameter')
        }
        // 添加状态
        this._status = PENDING
        // 添加状态
        this._value = undefined
        // 添加成功回调函数队列
        this._fulfilledQueues = []
        // 添加失败回调函数队列
        this._rejectedQueues = []
        // 执行handle
        try {
            handle(this._resolve.bind(this), this._reject.bind(this))
        } catch (err) {
            this._reject(err)
        }
    }
    // 添加resovle时执行的函数
    _resolve (val) {
        const run = () => {
            if (this._status !== PENDING) return
            // 依次执行成功队列中的函数,并清空队列
            const runFulfilled = (value) => {
                let cb;
                while (cb = this._fulfilledQueues.shift()) {
                    cb(value)
                }
            }
            // 依次执行失败队列中的函数,并清空队列
            const runRejected = (error) => {
                let cb;
                while (cb = this._rejectedQueues.shift()) {
                    cb(error)
                }
            }
            /* 如果resolve的参数为Promise对象,则必须等待该Promise对象状态改变后,
              当前Promsie的状态才会改变,且状态取决于参数Promsie对象的状态
            */
            if (val instanceof MyPromise) {
                val.then(value => {
                    this._value = value
                    this._status = FULFILLED
                    runFulfilled(value)
                }, err => {
                    this._value = err
                    this._status = REJECTED
                    runRejected(err)
                })
            } else {
                this._value = val
                this._status = FULFILLED
                runFulfilled(val)
            }
        }
        // 为了支持同步的Promise,这里采用异步调用
        setTimeout(run, 0)
    }
    // 添加reject时执行的函数
    _reject (err) {
        if (this._status !== PENDING) return
        // 依次执行失败队列中的函数,并清空队列
        const run = () => {
            this._status = REJECTED
            this._value = err
            let cb;
            while (cb = this._rejectedQueues.shift()) {
                cb(err)
            }
        }
        // 为了支持同步的Promise,这里采用异步调用
        setTimeout(run, 0)
    }
    // 添加then方法
    then (onFulfilled, onRejected) {
        const { _value, _status } = this
        // 返回一个新的Promise对象
        return new MyPromise((onFulfilledNext, onRejectedNext) => {
            // 封装一个成功时执行的函数
            let fulfilled = value => {
                try {
                    if (!isFunction(onFulfilled)) {
                        onFulfilledNext(value)
                    } else {
                        let res =  onFulfilled(value);
                        if (res instanceof MyPromise) {
                            // 如果当前回调函数返回MyPromise对象,必须等待其状态改变后在执行下一个回调
                            res.then(onFulfilledNext, onRejectedNext)
                        } else {
                            //否则会将返回结果直接作为参数,传入下一个then的回调函数,并立即执行下一个then的回调函数
                            onFulfilledNext(res)
                        }
                    }
                } catch (err) {
                    // 如果函数执行出错,新的Promise对象的状态为失败
                    onRejectedNext(err)
                }
            }
            // 封装一个失败时执行的函数
            let rejected = error => {
                try {
                    if (!isFunction(onRejected)) {
                        onRejectedNext(error)
                    } else {
                        let res = onRejected(error);
                        if (res instanceof MyPromise) {
                            // 如果当前回调函数返回MyPromise对象,必须等待其状态改变后在执行下一个回调
                            res.then(onFulfilledNext, onRejectedNext)
                        } else {
                            //否则会将返回结果直接作为参数,传入下一个then的回调函数,并立即执行下一个then的回调函数
                            onFulfilledNext(res)
                        }
                    }
                } catch (err) {
                    // 如果函数执行出错,新的Promise对象的状态为失败
                    onRejectedNext(err)
                }
            }
            switch (_status) {
                // 当状态为pending时,将then方法回调函数加入执行队列等待执行
                case PENDING:
                    this._fulfilledQueues.push(fulfilled)
                    this._rejectedQueues.push(rejected)
                    break
                // 当状态已经改变时,立即执行对应的回调函数
                case FULFILLED:
                    fulfilled(_value)
                    break
                case REJECTED:
                    rejected(_value)
                    break
            }
        })
    }
}

参考 Promise实现原理(附源码)

标签:

给我留言

Copyright © web前端技术开发个人博客 保留所有权利  京ICP备14060653号 Theme  Ality

用户登录