JavaScript 7 Promise

189 阅读1分钟

使用方法

function p() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            let result = Math.random()
            if (result > 0.5) {
                resolve(result)
            } else {
                reject(result)
            }
        }, 2000);
  }).then((res) => {
    console.log('success', res)
  }, err => {
    console.log('error', err)
  })
}

p()

封装

// 定义状态
const PENDING = Symbol('PENDING');
const FULFILLED = Symbol('FULFILLED');
const REJECTED = Symbol('REJECTED');

class MyPromise {

    constructor(handle) {
        // 状态初始值
        this._state = PENDING;
        // 存放结果
        this._value;
        // resolve 和 reject 数组
        this._fulilledQueue = [];
        this._rejectedQueue = [];

        try {
            handle(this.resolve, this.reject);
        } catch (e) {
            return this.reject(e);
        }
    }
    // 成功 调用
    handleFulilledQueue() {
        this._fulilledQueue.forEach(f => {
            f(this._value)
        })
    }
    // 失败 调用
    handleRejectQueue() {
        this._rejectedQueue.forEach(r => {
            r(this._value)
        })
    }
    // 成功 回调
    resolve = val => {
        if (this._state !== PENDING) return;
        if (val instanceof MyPromise) {
            val.then((res) => {
                this._status = FULFILLED;
                this._value = res;
                handleFulilledQueue();
            }, (err) => {
                this._status = REJECTED;
                this._value = err;
                handleRejectQueue();
            });
        } else {
            this._state = FULFILLED;
            this._value = val;
            this.handleFulilledQueue();
        }
    }
    // 失败 回调
    reject = val => {
        if (this._state !== PENDING) return;
        this._state == REJECTED;
        this._value = val;
        this.handleRejectQueue();
    }

    then(success, error) {
        if (this._state == FULFILLED) {
            success(this._value)
        }
        if (this._state == REJECTED) {
            error(this._value)
        }
        if (this._state == PENDING) {
            this._fulilledQueue.push(success)
            this._rejectedQueue.push(error)
        }
    }
}