Promise的基本使用

Wenn 于 2022-10-26 发布
const newPromise = new Promise((resolve,reject)=>{
    //resolve('成功')
    reject('失败')
})

new Promise((resolve,reject)=>{
    resolve(newPromise)  //如果传入的时一个Promise,则根据传入的Promise决定.then的执行
}).then(res=>console.log(res),err=>console.log(err))
new Promise((resolve,reject)=>{
    resolve({   //如果传入的是一个对象。并且这个对象实现了thenable,即有then方法,则依据then的返回值决定后续then的执行
        then:function((resolve,reject)=>{
        //resolve('成功')
        reject('失败')
    })
    })
}).then(res=>console.log(res),err=>console.log(err))

.then有返回值,默认是一个Promise对象,.then能链式调用的前提是因为它本身会返回一个Promise对象

  1. 如果我们返回的是一个普通值(数值、字符串、普通对象、undefined),那么这个普通的值会被作为一个新的Promise的resolve值;如果不写return,默认为返回一个undefined

    new Promise((res,rej)=>{
        res()
    }).then(res=>{}).then(res=>console.log(res)) //undefined   依旧会执行
    
  2. 如果我们返回的是一个Promise,则会依据这个Promise来处理之后的then

.catch也有一个返回值,同样是Promise,如果不在catch中抛出错误,则后续跟的then依旧会执行

new Promise((res,rej)=>{
    rej()
}).then(res=>{}).catch(err=>{
    console.log(err)
    return 'catch err'
}).then(res=>{
    console.log(res)   //'catch err' 此时得到的值为catch中return 的值
}).catch(err=>{
    console.log(err)   //不会执行
})

Promise类方法

resolve与reject方法一致,与下例

const promise = Promise.resolve({name:'xi',age:20})  //直接将一个对象作为返回值返回
promise.then(res=>console.log(res))  //{name:'xi',age:20}

all

当有多个promise时,所有的promise都为fulfilles时,返回一个数组的,一一对应,如果存在rejected状态,则只有rejected的状态结果

allSettled

多个promise时,返回一个数组,但是不会因为某一个rejected而中断

race

多个promise时,只要有一个为fulfilled,则以这个fulfilled结果返回,并不停止其他的promise,会执行完所有的promise

如果在所有promise都还没有结果的情况下,有某个rejected,则会直接返回rejected的结果

any

多个promise,当存在某一个rejected,不会结束,而是继续等待一个fulfilled,返回这个fulfilled的结果;如果多个promise都为rejected,则最后进行catch

Promise简单实现

const PROMISE_STATUS_PENDING = 'pending'
const PROMISE_STATUS_FULFILLED = 'fulfilled'
const PROMISE_STATUS_REJECTED = 'rejected'
class MyPromise{
    constructor(executor){
        this.status = PROMISE_STATUS_PENDING
        this.value = undefined
        this.reason = undefined
        
        const resolve=(value)=>{
            if(this.status === PROMISE_STATUS_FULFILLED){
                this.status = PROMISE_STATUS_FULFILLED
                queueMicrotask(()=>{
                    this.value = value
                    this.onFulfilled(this.value)
                })
            }
        }
        
        const reject=(reason)=>{
            if(this.status === PROMISE_STATUS_REJECTED){
                this.status = PROMISE_STATUS_REJECTED
                queueMicrotask((reason)=>{
                    this.reason = reason
                    this.onRejected(this.reason)
                })
            }
        }
        
        executor(resolve,reject)
    }
    
    then(onFulfilled,onRejected){
        this.onFulfilled = onFullfilled
        this.onRejected = onRejected
    }
}