promise

2020 M12 22

推荐阅读

https://juejin.cn/post/6844904116913700877

Promise(简化版)

// 先定义三个常量表示状态
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';

function MyPromise(fn) {
    this.status = PENDING;    // 初始状态为pending
    this.value = null;        // 初始化value
    this.reason = null;       // 初始化reason

    // 构造函数里面添加两个数组存储成功和失败的回调
    this.onFulfilledCallbacks = [];
    this.onRejectedCallbacks = [];

    // resolve方法参数是value
    resolve = (value) => {
        if (this.status === PENDING) {
            this.status = FULFILLED;
            this.value = value;
            // resolve里面将所有成功的回调拿出来执行
            this.onFulfilledCallbacks.forEach(callback => {
                callback(this.value);
            });
        }
    }

    // reject方法参数是reason
    reject = (reason) => {
        if (this.status === PENDING) {
            this.status = REJECTED;
            this.reason = reason;
            // resolve里面将所有失败的回调拿出来执行
            this.onRejectedCallbacks.forEach(callback => {
                callback(this.reason);
            });
        }
    }

    try {
        fn(resolve, reject);
    } catch (error) {
        reject(error);
    }
}

MyPromise.prototype.then = function (onFulfilled, onRejected) {
    if (this.status === FULFILLED) {
        onFulfilled(this.value)
    }
    if (this.status === REJECTED) {
        onRejected(this.reason);
    }
    // 如果还是PENDING状态,将回调保存下来
    if (this.status === PENDING) {
        this.onFulfilledCallbacks.push(onFulfilled);
        this.onRejectedCallbacks.push(onRejected);
    }
    return this
}



Promise.resolve

如果是Promise的实例,就直接返回。如果不是则用Promise包裹一下后返回

Promise.resolve = function (p) {
    if (p instanceof Promise)  return p;
    return new Promise(function (resolve) {
        resolve(p);
    });
}

Promise.reject

返回一个新的Promise实例,该实例的状态为rejected

Promise.reject = function (reason) {
    return new Promise(function (resolve,reject) {
        reject(reason);
    });
}

Promise.all

接收一个包含promsie的数组
不是promise的会转为promsie
必须等待所有的promise成功最后的结果才会resolve
其最终结果是一个数组,顺序与书写顺序一致
有一个失败则最终结果失败,返回第一个失败的reject

function all(promises=[]){
    return new Promise((resolve,reject)=>{
        let res=[]
        let count=0;
        let len=promises.length 
        if(len===0) return resolve(res)

        promises.forEach((p,i)=>{
            Promise.resolve(p).then((value)=>{
                count++
                res[i]=value 
                if(count===len){
                    resolve(res)
                }
            },(reason)=>{
                reject(reason)
            })
        })
    })
}

Promise.race

接收一个包含promsie的数组
不是promise的会转为promsie
不必等待所有的promise成功,最先完成的那个直接返回
一旦成功或失败不能转为其他状态,会立即结束,resolve和reject也会竞速

function race(promises = []) {
    return new Promise((resolve, reject) => {
        let len = promises.length
        if (len === 0) return resolve()
        for (let i = 0; i < len; i++) {
            const p = promises[i];
            Promise.resolve(p).then((value) => {
                return resolve(value)
            }, (reason) => {
                return reject(reason)
            })

        }
    })
}

catch

Promise中的catch是.then(null, rejection)或.then(undefined, rejection)的别名
用于指定发生错误时的回调函数
Promise.prototype.catch = function(onRejected) {
  this.then(null, onRejected);
}