javascript技巧

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript技巧 > JavaScript实现Promise功能

JavaScript模拟实现Promise功能的示例代码

作者:菜鸟小于

这篇文章主要为大家详细介绍了JavaScript如何模拟实现Promise功能,文中的示例代码讲解详细,对我们学习JavaScript有一定的帮助,需要的可以参考一下

模拟Promise的功能,  按照下面的步骤,一步一步

1. 新建是个构造函数

2. 传入一个可执行函数 函数的入参第一个为 fullFill函数 第二个为 reject函数; 函数立即执行, 参数函数异步执行

3. 状态一旦更改就不可以变更 只能 pending => fulfilled 或者 pending => rejected

4. then 的时候要处理入参的情况 successCallback 和failCallback 均可能为非函数

默认的 failCallback 一定要将异常抛出, 这样下一个promise便可将其捕获 异常冒泡的目的

5. then 中执行回调的时候要捕获异常 将其传给下一个promise

6. catch只是then的一种特殊的写法 方便理解和使用

7. finally 特点

8. Promise.resolve, Promise.reject 根据其参数返回对应的值 或者状态的Promise即可

9. Proise.all 特点

10. Proise.race 特点

const PENDING = 'pending' //等待
const FULFILLED = 'fulfilled' //成功
const REJECTED = 'rejected' //失败

const fulfilledCallback = [] //成功回调函数
const rejectedCallback = []  //失败回调函数

class MyPromise {
   
    constructor (executor) {
        
        try{
            executor(this.resolve, this.reject)
        } catch (e){
            this.reject(e)
        }
    }

    status = PENDING//promise的状态
    value = undefined//成功之后的值
    reason = undefined//失败之后的值
    fulfilledCallback = [] //成功回调函数
    rejectedCallback = []  //失败回调函数
    resolve = value => {
        //如果状态不是等待, 阻止程序继续往下执行
        if(this.status !== PENDING){
            return
        }
        this.status = FULFILLED
        this.value = value
        //判断成功回调是否存在,如果存在, 调用
        // this.fulfilledCallback && this.fulfilledCallback(this.value)
        while(this.fulfilledCallback.length) this.fulfilledCallback.shift()()

    }
    reject = reason => {
        //如果状态不是等待, 阻止程序继续往下执行
        if(this.status !== PENDING){
            return
        }
        this.status = REJECTED
        this.reason = reason
        //判断失败回调是否存在,如果存在, 调用
        // this.rejectedCallback && this.rejectedCallback(this.reason)
        while(this.rejectedCallback.length) this.rejectedCallback.shift()()
    }
    then = (fulfilledCallback, rejectedCallback) => {
        fulfilledCallback = fulfilledCallback ? fulfilledCallback : value => value
        rejectedCallback = rejectedCallback ? rejectedCallback : reason => {throw reason}
        let promise2 = new MyPromise((resolve, reject) => {
            
            //判断状态
            if(this.status === FULFILLED){
                setTimeout(() => {
                    try {
                        //判断x 传过来的可能是promise,先查看promise返回的结果,在决定是用resolve还是reject,
                        //如果是普通值,直接调用resolve
                        let x = fulfilledCallback(this.value)
                        //外面加载完,才能获取到promise2,用异步解决
                        resolvePromise(promise2,x,resolve, reject)
                    } catch (error) {
                        reject(error)
                    }
                    
                },0)
               
            }else if(this.status === REJECTED){
                
                setTimeout(() => {
                    try {
                        //判断x 传过来的可能是promise,先查看promise返回的结果,在决定是用resolve还是reject,
                        //如果是普通值,直接调用resolve
                        let x = rejectedCallback(this.reason)
                        //外面加载完,才能获取到promise2,用异步解决
                        resolvePromise(promise2,x,resolve, reject)
                    } catch (error) {
                        reject(error)
                    }
                    
                },0)
            }else{
                //等待状态
                this.fulfilledCallback.push(() => {
                    setTimeout(() => {
                        try {
                            //判断x 传过来的可能是promise,先查看promise返回的结果,在决定是用resolve还是reject,
                            //如果是普通值,直接调用resolve
                            let x = fulfilledCallback(this.value)
                            //外面加载完,才能获取到promise2,用异步解决
                            resolvePromise(promise2,x,resolve, reject)
                        } catch (error) {
                            reject(error)
                        }
                        
                    },0)
                });
                this.rejectedCallback.push(() => {
                    setTimeout(() => {
                        try {
                            //判断x 传过来的可能是promise,先查看promise返回的结果,在决定是用resolve还是reject,
                            //如果是普通值,直接调用resolve
                            let x = rejectedCallback(this.reason)
                            //外面加载完,才能获取到promise2,用异步解决
                            resolvePromise(promise2,x,resolve, reject)
                        } catch (error) {
                            reject(error)
                        }
                        
                    },0)
                });
            }
        })
        return promise2
    }

    static all (array) {
        let result= []
        let index = 0;

        return new MyPromise((resolve, reject) => {

            function addData (key, value) {
                result[key] = value
                index++
                if (index === array.length) {
                    resolve(result)
                }
            }

            for (let i = 0; i < array.length; i++) {
                
                if (array[i] instanceof MyPromise) {
                    //promise对象
                    array[i].then(value => addData(i, value), reason => reject(reason))
                } else {
                    //普通值, 放到数组里
                    addData(i, array[i])
                }
            }
        })

    }

    static resolve (value) {
        if(value instanceof MyPromise) return value
        return new MyPromise(resolve => resolve(value))

    }

    finally (callback) {
        return this.then(value => {
            return MyPromise.resolve(callback()).then(() => value)
        }, reason => {
            return MyPromise.resolve(callback()).then(() => {throw reason})
        })

    }

    catch (rejectedCallback) {
        return this.then(undefined, rejectedCallback)
    }

}

function resolvePromise(promise2,x,resolve, reject){

    if(x === promise2){
        return reject(new TypeError('啦啦啦啦'))
    }
    if(x instanceof MyPromise){
        //是promise
        //往下直接传
        x.then(resolve,reject)
    }else{
        //普通值
        resolve(x)
    }
}

module.exports = MyPromise;

到此这篇关于JavaScript模拟实现Promise功能的示例代码的文章就介绍到这了,更多相关JavaScript实现Promise功能内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文