【实现】Promise

很多时候,我们这样使用promise

let p = new Promise((resolve, reject) => {
    if (1 < 2) { //判断条件
        resolve(1);
    } else {
        reject(2);
    }
})

p
.then(val => {console.log(val);})
.catch(err => {console.log(err)});

1.声明

所以我们需要声明一个类 Promise,它的参数((resolve, reject) => {})是一个表达式 executor

class RePromise{
    constructor (executor) {
        let resolve = () => {};
        let reject = () => {};
        executor (resolve, reject);
    }
  }

2.基本状态

promise的三种基本状态:pending,fulfilled,rejected

class RePromise{
    constructor (executor) {
        this.state = 'pending';
        this.value = null;
        this.reason = null;
        let resolve = (value) => {
            this.state === 'pending' ? this.state = 'fulfilled' : '';
            this.value = value;
        };
        let reject = (reason) => {
            this.state === 'pending' ? this.state = 'rejected' : '';
            this.reason = reason;
        };
        try {
            executor (resolve, reject);
        } catch (err) {
            reject(err);
        }
    }
}

3.then catch

class RePromise{
    constructor (executor) {
        this.state = 'pending';
        this.value = null;
        this.reason = null;
        this.onResolvedCallback = [];
        this.onRejectedCallback = [];
        let resolve = (value) => {
            this.state === 'pending' ? this.state = 'fulfilled' : '';
            this.value = value;
        };
        let reject = (reason) => {
            this.state === 'pending' ? this.state = 'rejected' : '';
            this.reason = reason;
        };
        try {
            executor (resolve, reject);
        } catch (err) {
            reject(err);
        }
    }
    then (onFulfilled,onRejected) {
        if (this.state === 'fulfilled') onFulfilled(this.value);
        this.catch(onRejected);
        return this;
    }
    catch (onRejected) {
        if (this.state === 'rejected') onRejected(this.reason);
    }
}

4.异步

使用 onResolvedCallback onRejectedCallback 暂存then或者catch的函数参数,待执行完成后调用

class RePromise{
    constructor (executor) {
        console.log(123123)
        this.state = 'pending';
        this.value = null;
        this.reason = null;
        this.onResolvedCallback = [];
        this.onRejectedCallback = [];
        let resolve = (value) => {
            this.state === 'pending' ? this.state = 'fulfilled' : '';
            this.value = value;
            this.onResolvedCallback.forEach(fn => fn());
        };
        let reject = (reason) => {
            this.state === 'pending' ? this.state = 'rejected' : '';
            this.reason = reason;
            this.onRejectedCallback.forEach(fn => fn());
        };
        try {
            executor (resolve, reject);
        } catch (err) {
            reject(err);
        }
    }
    then (onFulfilled,onRejected) {
        if (this.state === 'fulfilled') onFulfilled(this.value);
        if (this.state === 'pending') {
            this.onResolvedCallback.push(()=> {onFulfilled(this.value)});
        }
        this.catch(onRejected);
        return this;
    }
    catch (onRejected) {
        if (this.state === 'rejected') onRejected(this.reason);
        if (this.state === 'pending') {
            this.onRejectedCallback.push(()=> {onRejected(this.value)});
        }
    }
}

let promise = new RePromise((resolve, reject) => {
    setTimeout(()=> {
        resolve(2);
    }, 2000)
})

promise
.then(val => {console.log('then1',val);})
.catch(err => {console.log('catch',err)});

5.链式调用

then方法,注意这几种可能:

  • return promise:resolve值传递给下一个then
  • return 函数:return值传递
  • 表达式:执行
function resolvePromise(promise2, x, resolve, reject){
    if (x === promise2) reject('自身循环');
    try {
        if (typeof x === 'object' || typeof x === 'function') {
            let then = x.then;
            // x是promise
            if (then && typeof then === 'function') {
                x.then(
                    val => resolvePromise(promise2, val, resolve, reject),
                    err => {reject(err)}
                );
            } else { //x为普通函数
                resolve(x);
            }
        } else { // x为普通值
            resolve(x);
        }
    } catch (err) {
        reject(err);
    }
  }

class RePromise{
    constructor (executor) {
        this.state = 'pending';
        this.value = null;
        this.reason = null;
        this.onResolvedCallback = [];
        this.onRejectedCallback = [];
        let resolve = (value) => {
            this.state === 'pending' ? this.state = 'fulfilled' : '';
            this.value = value;
            this.onResolvedCallback.forEach(fn => fn());
        };
        let reject = (reason) => {
            this.state === 'pending' ? this.state = 'rejected' : '';
            this.reason = reason;
            this.onRejectedCallback.forEach(fn => fn());
        };
        try {
            executor (resolve, reject);
        } catch (err) {
            reject(err);
        }
    }
    then (onFulfilled,onRejected) {
        onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : val => val;
        onRejected = typeof onRejected === 'function' ? onRejected : err => {throw err};
        let promise2 = new RePromise((resolve, reject) => {
            if (this.state === 'fulfilled') {
                let x = onFulfilled(this.value);
                resolvePromise(promise2, x, resolve, reject);
            }
            if (this.state === 'reject') {
                try {
                    let x = onRejected(this.reason);
                    resolvePromise(promise2, x, resolve, reject);
                } catch (err) {
                    resolvePromise(promise2, err, resolve, reject);
                }
            }
            if (this.state === 'pending') {
                this.onResolvedCallback.push(()=> {
                    let x = onFulfilled(this.value);
                    resolvePromise(promise2, x, resolve, reject);
                });
                this.onRejectedCallback.push(()=> {
                    let x = onRejected(this.reason);
                    resolvePromise(promise2, x, resolve, reject);
                });
            }
        })
        return promise2;
    }
    catch (onRejected) {
        if (this.state === 'rejected') onRejected(this.reason);
        if (this.state === 'pending') {
            this.onRejectedCallback.push(()=> {onRejected(this.value)});
        }
    }
}

let promise = new RePromise((resolve, reject) => {
    setTimeout(()=> {
        resolve(2);
    }, 2000)
})

promise
.then(val => {return new RePromise((resolve, reject)=>{resolve(123)})}, err=> console.log('err',err))
.then(val => {return val+1}, err=> console.log('err',err))
.then(val => console.log('then2', val), err=> console.log('err',err))
.catch(err => {console.log('catch',err)})

😊

results matching ""

    No results matching ""