美文网首页
如何手写一个Promise

如何手写一个Promise

作者: 小豆soybean | 来源:发表于2021-09-28 01:02 被阅读0次

    参考文章:https://www.jianshu.com/p/23f34c35da0c

    const { resolve } = require("path/posix");
    
    class Promise {//Promise里面参数传一个匿名函数,函数的参数是resolve和reject
        // 初始属性设置
        constructor(executor){
            this.promiseState = 'pending';
            this.promiseResult = null;
             // 保存回调函数
            this.callbacks = [];
            
            // resolve都写在constructor里面
            const resolve = (value) => {
                // 判断状态 让Promise只执行一次。
                if (this.promiseState !== 'pending') return;
                this.promiseState = 'fulfilled';
                this.promiseResult = value;
                // 要包到setTimeout里面
                setTimeout(()=> {
                    this.callbacks.forEach(cb => cb.onResolved(value));
                })
            }
    
            const reject = (err) => {
                if (this.callbacks !== 'pending') return;
                this.promiseState = 'rejected';
                this.promiseResult = err;
                setTimeout(()=>{
                    this.callbacks.forEach(cb => cb.onRejected(err));
                })
            }
            try {
                executor(resolve, reject);//这里resolve是传递给儿子了, 儿子完成了直接调用就行了。
            } catch (error) {
                reject(error);     
            }
        }
        // then方法
        then(onResolved, onRejected) {
            // 这里处理异常穿透。假如这个then里面啥都没写,下一个then里面写了一个promise还要可以继续执行下去。
            
            if (typeof onResolved != 'function') {
                onResolved = val => val;
            }
            if (typeof onRejected !== 'function') {
                onRejected = error => {throw error;} //随便原样返回就行
            }
            
            // then里面是返回了一个Promise this想要一直穿透就要用箭头函数
            const handleCallback = (callback) => {
                try {
                    let res = callback(this.promiseResult);
                    if (res instanceof Promise) {
                        // 因为这里是一个promise,处理一下值搞进resolve里面,这样下一个then就能拿到了。
                        res.then(val => resolve(val), error => reject(error));
                    } else {
                        resolve(res);
                    }
                } catch (error) {
                    reject(error);
                }
            }
    
            //写一个handleCallback函数。
            if (this.promiseState === 'fulfilled') {
                // !!!这里要包一层setTimeout
                setTimeout(()=> {
                    handleCallback(onResolved)
                });
            }
            if (this.promiseState === 'rejected') {
                setTimeout(()=> {
                    handleCallback(onRejected)
                })
            }
            if (this.promiseState === 'pending') {
                this.callbacks.push({
                    onResolved: () => {
                        handleCallback(onResolved)
                    },
                    onRejected: () => {
                        handleCallback(onRejected)
                    }
                })
            }
        }
    
        catch(onRejected) {
            return this.then(undefined, onRejected);
        }
    
        // static 方法
        static resolve(value) {
            return new Promise((resolve, reject) => {
                if (value instanceof Promise) {
                    value.then( val =>resolve(val), error => reject(error))
                } else {
                    resolve(value);
                }
            })
        }
    
        static rejected(error) {
            // 这里只有reject
            return new Promise((resolve, reject) => {
                 reject(error)
            });
        }
    
        // all方法
        static all(promiseArrays) {
            return new Promise((resolve, reject) => {
                let result = [];
                let length = promiseArrays.length;
                promiseArrays.forEach(promiseObj => {
                    promiseObj.then(val => {
                        result.push(val);
                        // 由于是多个异步的关系,所以需要判断是否都执行完毕。
                        if (result.length === length) {
                            resolve(result);
                        }
                    }, error => {
                        reject(error)
                    })
    
                })
            })
        }
    
        // race方法
        static race(promiseArrays) {
            return new Promise((resolve, reject) => {
                promiseArrays.forEach(promiseObj => {
                    promiseObj.then((value)=>{
                        resolve(value)
                    }, error => {
                        reject(error)
                    })
                })
    
            })
        }
    
    }
    

    相关文章

      网友评论

          本文标题:如何手写一个Promise

          本文链接:https://www.haomeiwen.com/subject/otllnltx.html