Promise

57 阅读3分钟

一篇学完Promise和查阅了许多资料和历史后留的笔记

先上概念

Promise是一个对象

Promise是ES6提出的一个异步解决方案,这个方案主要是解决了以前异步问题的困境。

Promise本身是一个同步代码,但是他的then方法等是异步代码,这些异步代码都是属于微队列的,会比宏队列的任务优先级更高

这里存在几个小点,在ES6之前 js是怎么异步问题的?解决了怎么样的异步的问题?

在ES6之前 JS主要依靠回调函数解决异步问题,但是因此引出了第二个问题,大量的异步回调会产生“回调地狱”,在大量回调的中不仅让代码非常不优雅,而且在其中一个环节如果出现错误,就会导致后面的回调纷纷不能执行

在ES6的时候才真正出现了官方解决回调的的问题,功能十分强大,可以链式调用,避免了环环嵌套

注意事项

Promise的状态一旦更改,除了一些特殊情况(例如在then中又调用了Promise对象,那就会以新的Promise对象的状态为主) 状态有3个状态:

1.fulfilled(实现),

2.rejected(拒绝),

3.pending(发送中)

// 前两个都是过去式代表已经发生,最后一个是现在进行时代表正在进行,

实例方法

then()

then可以传入2个回调函数resolve,reject,传入参数这些状态是可选的,注意then返回的是一个promise对象,可以进行链式调用

catch()

catch可以捕获rejected状态返回的参数,可以说是then第二个回调的分离

finally()

无论是什么成功或失败,都会返回一个结果

静态方法

all([])

传入一组请求(或一个普通参数),当里面所有内容为fulfiled状态时才回返回这组Promise对象的集合,如果出现一个rejected状态就返回为第一个对象 。 // 普通参数都作为fulfilled状态处理

race([])

竞赛

一组请求中返回第一个完成的请求

Promise源码

   class testPromise{
    static pending = 'pending'
    static fulfilled = 'fulfilled'
    static rejected = 'rejected'
    status = null
    result = null
    resTick = []
    rejTick = []
    constructor(callback){
        // resolve 函数
        let resolve = (values)=>{
            this.status = testPromise.pending
            this.result = values
            this.resTick.forEach(i =>{
                i()
            })
        }
        // reject 函数
        let reject = (reason)=>{
            this.status = testPromise.rejected
            this.result = reason
        }
        try {
            callback(resolve,reject)
            
        } catch (error) {
            reject(error)
        }
    }
    // then方法 
    resolvePromise(x,resolve,reject){
            if (x instanceof testPromise) { // 判断传来的值是不是Promise对象
                x.then(res =>{
                    resolve(res)
                })        // 如果是 就可以调用他的then的值 形成链式调用
                x.catch(res=>{
                    reject(res)
                })
            }else{ // 如果不是直接返回该值
                resolve(x)
            }
    }
    then(res,err){
        // then 链式调用  返回一个promise对象
        const thenPromise = new testPromise((resolve,reject)=>{
                if (this.status === testPromise.fulfilled) {
                    let x = res(this.result)
                    this.resolvePromise(x,resolve,reject)  // 将值返回给下一个then
                }else if(this.status === testPromise.rejected){
                    let x = err(this.result)
                    this.resolvePromise(x,resolve,reject)  // 将值返回给下一个then
                } 
                else if(this.status === testPromise.pending) {
                    this.resTick.push(()=>{
                        let x = res(this.result)
                        this.resolvePromise(x,resolve,rejuct) 
                    })
                    this.rejTick.push(()=>{
                        let y = err(this.result)
                        this.resolvePromise(y,resolve,rejuct) 
                    })
                }
        })

        return thenPromise
    }

    catch(res){
         if (this.status === testPromise.rejected) {
                    let x = res(this.result)
                    this.resolvePromise(x,resolve,reject)  // 将值返回给下一个then
                } else if(this.status === testPromise.pending) {
                    this.rejTick.push(()=>{ 
                        let x = res(this.result)
                        this.resolvePromise(x,resolve,reject) 
                    })
                }
    }

    static resolve(res){
        return new testPromise((resolve,reject)=>{
            resolve(res)
        })
}

static reject(reason){
        return new testPromise((resolve,reject)=>{
            reject(reason)
        })
    }
static all(arr){
const allResult = []
let count = 0
return new testPromise((resolve,reject)=>{
        const addData = (index,item)=>{
            allResult[index] = item
            count++
            if (count === arr.length)resolve(allResult)
        }
        arr.forEach((item,index)=>{
                if (item instanceof testPromise) {
                    item.then(res=>{
                        addData(index,res)
                    },err=>{
                        reject(err)
                    })
                }else{
                    addData(index,item)
                }
        })
})
    // 参数不一定非得是数组
    // p的状态由p1、p2、p3决定,分成两种情况。
    
    // (1)只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。
    
    // (2)只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。
   
}

static race(arr){

    // console.log(123);
//    return new testPromise((resolve,reject)=>{
//        for (let i = 0; i < arr.length; i++) {
//         console.log(arr[i]);
//             arr[i].then(resolve,reject)
//         }
//     })
    return new testPromise((resolve,reject)=>{
     arr.forEach((i)=>{
            if (i instanceof testPromise) {
                i.then(resolve,reject)
            }else{
                reject(i)
            }
     })
    })
}

}