• 手写Promise


    简单版:

    function MyPromise(exec) {
        const that = this;
        that.state = 'PENDING';
        that.value = null;
        that.resolvedCallbacks = [];
        that.rejectedCallbacks = [];
        function resolve(v) {
            if(that.state === 'PENDING') {
                that.state = 'RESOLVED';
                that.value = v;
                that.resolvedCallbacks.map(cb => cb(that.v));
            }
        }
        function reject(r) {
            if(that.state === 'PENDING') {
                that.state = 'REJECTED';
                that.value = r;
                that.rejectedCallbacks.map(cb => cb(that.v));
            }
        }
        try {
            exec(resolve, reject)
        } catch (e) {
            reject(e);
        }
    }
    MyPromise.prototype.then = function(onfulfilled, onrejected) {
        const that = this;
        onfulfilled = typeof onfulfilled === 'function' ? onfulfilled : v => v;
        onrejected = typeof onrejected === 'function' ? onrejected : r => {throw r};
        if(that.state === 'PENDING') {
            that.resolvedCallbacks.push(onfulfilled);
            that.rejectedCallbacks.push(onrejected);
        }
        if(that.state === 'RESOLVED') {
            onfulfilled(that.value);
        }
        if(that.state === 'REJECTED') {
            onrejected(that.value);
        }
    }

    完整版:

    class MyPromise {
        constructor (execute) {
            if(typeof execute !== 'function') throw new Error('type error');
            const that = this;
            that.status = 'PENDING';
            that.value = null;
            that.resolvedCallbacks = [];
            that.rejectedCallbacks = [];
            try{
                execute(that._resolve.bind(that), that._reject.bind(that));
            } catch (e) {
                that._reject(e);
            }
        }
        _resolve (val) {
            const that = this;
            const run = () => {
                if (that.status !== 'PENDING') return;
                const runFulfilled = (value) => {
                    let cb;
                    while (cb = that.resolvedCallbacks.shift()) {
                        cb(value);
                    }
                }
                const runRejected = (error) => {
                    let cb;
                    while (cb = that.rejectedCallbacks.shift()) {
                        cb(error);
                    }
                }
                if (val instanceof MyPromise) {
                    val.then(value => {
                        that.value = value;
                        that.status = 'RESOLVED';
                        runFulfilled(value);
                    }, err => {
                        that.value = err;
                        that.status = 'REJECTED';
                        runRejected(err);
                    })
                } else {
                    that.value = val;
                    that.status = 'RESOLVED';
                    runFulfilled(val);
                }
            }
            setTimeout(run, 0)
        }
        _reject (err) { 
            const that = this;
            if (that.status !== 'PENDING') return;
            const run = () => {
                that.status = 'REJECTED';
                that.value = err;
                let cb;
                while (cb = that.rejectedCallbacks.shift()) {
                    cb(err);
                }
            }
            setTimeout(run, 0)
        }
        then (onFulfilled, onRejected) {
            const that = this;
            return new MyPromise((onFulfilledNext, onRejectedNext) => {
            let fulfilled = value => {
                try {
                    if (typeof onFulfilled !== 'function') {
                        onFulfilledNext(value);
                    } else {
                        let res =  onFulfilled(value);
                        if (res instanceof MyPromise) {
                            res.then(onFulfilledNext, onRejectedNext);
                        } else {
                            onFulfilledNext(res);
                        }
                    }
                } catch (err) {
                    onRejectedNext(err);
                }
            }
            let rejected = error => {
                try {
                    if (typeof onRejected !== 'function') {
                        onRejectedNext(error);
                    } else {
                        let res = onRejected(error);
                        if (res instanceof MyPromise) {
                            res.then(onFulfilledNext, onRejectedNext);
                        } else {
                            onFulfilledNext(res);
                        }
                    }
                } catch (err) {
                    onRejectedNext(err);
                }
            }
            switch(that.status) {
                case 'PENDING':{
                    that.resolvedCallbacks.push(onFulfilled);
                    that.rejectedCallbacks.push(onRejected);
                };break;
                case 'RESOLVED':onFulfilled(that.value);break;
                case 'REJECTED':onRejected(that.value);break;
            }
          })
        }
        _catch (onRejected) {
          return this.then(undefined, onRejected)
        }
        static resolve (value) {
          if (value instanceof MyPromise) return value
          return new MyPromise(resolve => resolve(value))
        }
        static reject (value) {
          return new MyPromise((resolve ,reject) => reject(value))
        }
        static all (list) {
          return new MyPromise((resolve, reject) => {
            let values = []
            let count = 0
            for (let [i, p] of list.entries()) {
              this.resolve(p).then(res => {
                values[i] = res
                count++
                if (count === list.length) resolve(values)
              }, err => {
                reject(err)
              })
            }
          })
        }
        static race (list) {
          return new MyPromise((resolve, reject) => {
            for (let p of list) {
              this.resolve(p).then(res => {
                resolve(res)
              }, err => {
                reject(err)
              })
            }
          })
        }
        finally (cb) {
          return this.then(
            value  => MyPromise.resolve(cb()).then(() => value),
            reason => MyPromise.resolve(cb()).then(() => { throw reason })
          );
        }
    }
  • 相关阅读:
    关于量子计算机的一些整理 (精心整理原创) (1)
    自然语言交流系统 phxnet团队 创新实训 个人博客 (一)
    自然语言交流系统 phxnet团队 创新实训 项目博客 (一)
    double类型保留2位小数
    main函数位置
    java中main函数解析
    关于函数声明的小知识点
    数据帧、数据包、数据报以及数据段
    chrome 常用快捷键(可以摆脱鼠标哦)
    chrome 如何利用快捷键将光标移动到地址栏
  • 原文地址:https://www.cnblogs.com/qq965921539/p/13635907.html
Copyright © 2020-2023  润新知