JavaScript手写简版Promise

1、介绍

        什么是promise?MDN中对其的介绍是:Promise 对象表示异步操作最终的完成(或失败)以及其结果值。个 Promise 是一个代理,它代表一个在创建 promise 时不一定已知的值。它允许你将处理程序与异步操作的最终成功值或失败原因关联起来。这使得异步方法可以像同步方法一样返回值:异步方法不会立即返回最终值,而是返回一个 promise ,以便在将来的某个时间点提供该值。(Promise - JavaScript | MDN)

2、简版promise

        接下来将根据promise规范,一步一步书写一个简版promise。

2.1、promise的三种状态

        一个 Promise 必然处于以下三种状态之一:初始状态-待定(pending)、已兑现(fulfilled)、已拒绝(rejected),且状态不可逆。当Promise中有throw的话,相当于执行了reject。

JavaScript手写简版Promise_第1张图片

JavaScript手写简版Promise_第2张图片

class MyPromise {
    constructor(fun){
        // 初始化值
        this.PromiseState = 'pending'
        this.PromiseResult = null

        // 确保resolve和reject的this指向永远指向当前的MyPromise实例,防止随着函数执行环境的改变而改变;
        this.resolve = this.resolve.bind(this)
        this.reject = this.reject.bind(this)

        // 捕获异常
        try {
            fun(this.resolve, this.reject)
        } catch (error) {
            this.reject(error)
        }
    }

    resolve(value){
        if(this.PromiseState !== 'pending') return // 状态不可逆

        this.PromiseState = 'fulfilled'
        this.PromiseResult = value
    }

    reject(resone){
        if(this.PromiseState !== 'pending') return

        this.PromiseState = 'rejected'
        this.PromiseResult = resone
    }
}
2.2、then()

   then()方法最多接受两个参数:用于 Promise 兑现(fulfilled)和拒绝(rejected)情况的回调函数。

class MyPromise {
    constructor(fun){
         // ... 其余代码

        this.onFulfilledSack = []
        this.onRejectedStack = []
    }
      resolve(value){
        // ...

        while(this.onFulfilledSack.length > 0){
            this.onFulfilledSack.shift()(this.PromiseResult)
        }
    }

    reject(resone){
        // ...

        while(this.onRejectedStack.length > 0){
            this.onRejectedStack.shift()(this.PromiseResult)
        }
    }

    then(onFulfilled, onRejected){
        // 当回调不是一个函数时,将其置为函数
        onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : (val) => val
        onRejected = typeof onRejected === 'function' ? onRejected : (val) => val

        if(this.PromiseState === 'fulfilled'){
            onFulfilled(this.PromiseResult)
        }else if(this.PromiseState === 'rejected'){
            onRejected(this.PromiseResult)
        }else{
            // 当resolve或者reject在异步处理后才执行时,将回调放置到对应的队列中
            this.onFulfilledSack.push(onFulfilled.bind(this))
            this.onRejectedStack.push(onRejected.bind(this))
        }
    }
}
2.3、链式调用 

        修改then()方法,使其返回一个myPromise实例。

class MyPromise {
    // ... 其他代码

    then(onFulfilled, onRejected){
        // 当回调不是一个函数时,将其置为函数
        onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : (val) => val
        onRejected = typeof onRejected === 'function' ? onRejected : (val) => val

        return new MyPromise((resolve, reject) => {
            const resolvePromise = (cb) => {
                let res = cb(this.PromiseResult) // 获取上一个then的返回
                try {
                    if(res && res === resolvePromise){
                        throw new Error('do not return self')
                    }else if(res instanceof MyPromise){
                        res.then(resolve, reject)
                    }else{
                        resolve(res)
                    }
                } catch (error) {
                    reject(error)
                    throw new Error(error)
                }
            }

            if(this.PromiseState === 'fulfilled'){
                resolvePromise(onFulfilled)
            }else if(this.PromiseState === 'rejected'){
                resolvePromise(onRejected)
            }else{
                this.onFulfilledSack.push(()=> resolvePromise(onFulfilled.bind(this)))
                this.onRejectedStack.push(()=> resolvePromise(onRejected.bind(this)))
            }
        })
    }
}
2.4 all()

        静态方法接受一个 Promise 可迭代对象作为输入,并返回一个 Promise。当所有输入的 Promise 都被兑现(fulfilled)时,返回的 Promise 也将被兑现(fulfilled)(即使传入的是一个空的可迭代对象),并返回一个包含所有兑现值的数组。如果输入的任何 Promise 被拒绝(rejected),则返回的 Promise 将被拒绝(rejected),并带有第一个被拒绝的原因。

JavaScript手写简版Promise_第3张图片

class MyPromise {
    // ... 其它代码

    static all(promises){
        let result = []
        let count = 0

        return new MyPromise((resolve, reject)=>{
            promises.forEach((promise, index)=>{
                if(promise instanceof MyPromise){
                    promise.then((value)=>{
                        result[index] = value
                        count ++
        
                        if(count === promises.length){
                            resolve(result)
                        }
                    }, (err)=>{
                        reject(err)
                        throw new Error(err)
                    })
                }else{
                    result[index] = promise
                    count ++
                }
            })
        })
    }
}
 2.5 完整代码
class MyPromise {
    constructor(fun){
        // 初始化值
        this.PromiseState = 'pending'
        this.PromiseResult = null
        this.onFulfilledSack = []
        this.onRejectedStack = []

        // 确保resolve和reject的this指向永远指向当前的MyPromise实例,防止随着函数执行环境的改变而改变;
        this.resolve = this.resolve.bind(this)
        this.reject = this.reject.bind(this)

        // 捕获异常
        try {
            fun(this.resolve, this.reject)
        } catch (error) {
            this.reject(error)
        }
    }

    resolve(value){
        if(this.PromiseState !== 'pending') return // 状态不可逆

        this.PromiseState = 'fulfilled'
        this.PromiseResult = value

        while(this.onFulfilledSack.length > 0){
            this.onFulfilledSack.shift()(this.PromiseResult)
        }
    }

    reject(resone){
        if(this.PromiseState !== 'pending') return

        this.PromiseState = 'rejected'
        this.PromiseResult = resone

        while(this.onRejectedStack.length > 0){
            this.onRejectedStack.shift()(this.PromiseResult)
        }
    }

    then(onFulfilled, onRejected){
        // 当回调不是一个函数时,将其置为函数
        onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : (val) => val
        onRejected = typeof onRejected === 'function' ? onRejected : (val) => val

        return new MyPromise((resolve, reject) => {
            const resolvePromise = (cb) => {
                let res = cb(this.PromiseResult) // 获取上一个then的返回
                try {
                    if(res && res === resolvePromise){
                        throw new Error('do not callBack self')
                    }else if(res instanceof MyPromise){
                        res.then(resolve, reject)
                    }else{
                        resolve(res)
                    }
                } catch (error) {
                    reject(error)
                    throw new Error(error)
                }
            }

            if(this.PromiseState === 'fulfilled'){
                resolvePromise(onFulfilled)
            }else if(this.PromiseState === 'rejected'){
                resolvePromise(onRejected)
            }else{
                this.onFulfilledSack.push(()=> resolvePromise(onFulfilled.bind(this)))
                this.onRejectedStack.push(()=> resolvePromise(onRejected.bind(this)))
            }
        })
    }

    static all(promises){
        let result = []
        let count = 0

        return new MyPromise((resolve, reject)=>{
            promises.forEach((promise, index)=>{
                if(promise instanceof MyPromise){
                    promise.then((value)=>{
                        result[index] = value
                        count ++
        
                        if(count === promises.length){
                            resolve(result)
                        }
                    }, (err)=>{
                        reject(err)
                        throw new Error(err)
                    })
                }else{
                    result[index] = promise
                    count ++
                }
            })
        })
    }
}

你可能感兴趣的:(javascript,开发语言)