promise总结

promise用于控制异步操作,本文涉及promise对象、链式调用、promise.all、promise.race、手写promise

promise对象

生命周期(三个状态)

1.pending(promise异步操作进行中)
2.Fulfilled(异步操作成功完成)
3.Rejected(异步操作未成功完成)
4.可通过resolve( )reject( )变更状态为Fulfilled、Rejected。

promise.then

  • promise状态改变时,通过then( )采取相应的操作。
  • then( )接收两个函数作为参数。
  • 第一个参数在状态变为Fulfilled时调用。
  • 第二个参数在状态变为Rejected时调用。
  • resolve()reject()可向将自身的参数传递给状态处理程序,完成后续操作。
  • promise.catch()类似于then( ),只接收一个拒绝处理程序方法,在状态为Rejected时调用。相当于promise.then(null,function())
  • then()catch()会被加入到微任务队列中,状态变更后由任务队列调度执行。

创建

通过构造函数创建。

1.创建未完成的promise
const promise = new Promise((resolve,reject)=>{
    console.log("promise");
    const status  = "Fulfilled";
    resolve( “status”);
})

promise.then((status)=>{
    console.log(status)
},(status)=>{
    console.log(status)
})

上段代码执行情况:

  • 构造函数接收一个执行器函数作为参数,执行器函数中包含所要控制的操作。
  • "promise"正常打印,resolve( )将promise状态变为Fulfilled。
  • then()接收两个参数,状态变为Fullfilled时,执行第一个函数,打印“resolved”
2.创建已完成的promise
const promiseFulfilled = Promise.resolve("Fulfilled");
promiseFulfilled.then( (status) => {console.log(status) } );

只有Fulfilled状态,Promise.rejected()同理。

实例:发起请求后续进行处理。

const getInfo = (url) => {
    return new Promise((resolve,reject)=>{
        const xhr = new XMLHttpRequest();
        xhr.open("Get",url,true);
        xhr.onreadystatechange = () => {
            if(xhr.readyState === 4){
                if(xhr.status >= 200 && xhr.status <= 300 || xhr.status === 304){
                    resolve(xhr.response); //请求到数据后传给处理程序
                }
                else {
                    reject()
                }
            }
        }
        xhr.send();
    })
}

getInfo("http://rap2.taobao.org:38080/app/mock/244929/example/1582096559375").then((res)=>{
    console.log(res);
},()=>{
    console.log(`错误`)
})  //在`then()`中进行具体处理

promise链式调用

  • then()除了参与事件处理程序的调度,还会返回一个新的promise。
  • 全新的promise也有自己的then(),可设置自己的处理程序,同时又可返回新的promise。
  • 先前的promise处理程序完成后会继续执行下层promise的处理程序,实现链式调用。
  • 处理程序可以有返回值,返回值可传入新生promise处理程序作为参数。
const p1 = new Promise((resolve,reject)=>{
    resolve(42);
})

p1.then((value)=>{
    console.log(value);
    return value+1;
}).then((value)=>{
    console.log(value);
})
//依次打印
//42
//43

通过链式调用捕获错误

const sex = "female" ;
const p1 = new Promise((resolve,reject)=>{
    resolve(sex);
})
p1.then((sex)=>{
    if(sex === "male"){
        console.log(sex);
    }
    else throw new Error("不要female")
}).catch((error)=>{
    console.log(error.message);
})

比如我是gay,性别为male就打印,否则就报错,并由下一级promise处理程序打印错误信息。

promise链中返回promise

上述链式调用中,处理程序返回值为一般的数据,也可返回Thenable数据(简单理解,可以调用data.then()的数据,如promise)。

    const p1 = new Promise((resolve,reject) => {
        resolve(42);
    })

    const p2 = new Promise((resolve,reject) => {
        resolve(43);
    })

    p1.then((value) => {      //处理程序1
        console.log(value);
        return p2;                      
    }).then((value)=>{          //处理程序2
        console.log(value)
    })

    //依次打印42、438

上代码中:

  • p1成功处理程序返回p2。
  • 处理程序1绑定到p1上,处理程序2绑定到p1.then()上(而不是在p2上)。
  • 但只有p2处理后才会执行处理程序2。例如p2Rejected时,只能触发处理程序2的拒绝处理程序,不会触发成功处理程序。
  • 返回promise不会改变promise执行器执行时机。
  • 在处理程序中新建promise可推迟promise(代码中未展现)。

监听多个promise

promise.all

  • 可同时监听多个promise。
  • 唯一参数为包含promise的可迭代对象(如数组),非promise类型会被转化为相应promise对象。
  • 返回一个promise。
  • 可迭代对象中所有promise都被完成时,返回的promise才会被完成。
全部完成时

各个promse传递值组成数组传给返回的promise

    const p1 = new Promise((resolve,reject)=>{
        resolve(42);
    });
    
    const p2 = new Promise((resolve,reject)=>{
        resolve(43);
    });
    
    const p3 = new Promise((resolve,reject)=>{
        resolve(44);
    });
    
    const p4 =Promise.all([p1,p2,p3]);
    
    p4.then((result)=>{
        console.log(result);       //[42,43,44]
    });
部分拒绝时

promise传入值为第一个被拒绝的promise所传递的值。

    const p1 = new Promise((resolve,reject)=>{
        resolve(42);
    });
    
    const p2 = new Promise((resolve,reject)=>{
        reject(43);
    });

    const p3 = new Promise((resolve,reject)=>{
        resolve(44);
    });
    
    const p4 =Promise.all([p1,p2,p3]);

    p4.catch((value) => {
        console.log(value);     //43
    })

promise.race

  • 与promise.all相似,传入含proimise的可迭代对象(非promise对象会转化为相应promise),返回一个promise。
  • 各个promise相互竞争,promise.race返回最先完成的promise。
场景1
    const p1 = new Promise((resolve,reject) => {
        resolve(42);
    });

    const p2 = new Promise((resolve,reject) => {
        resolve(43);
    })

    const p3 = new Promise((resolve,reject) => {
        resolve(44);
    })

    const p4 = Promise.race([p1,p2,p3])

    p4.then((value) => {
        console.log(value)    //42
    })
场景2
    const p1 = new Promise((resolve,reject) => {
        setTimeout(() => {resolve(42)},2000);
    });

    const p2 = new Promise((resolve,reject) => {
        resolve(43);
    })

    const p3 = new Promise((resolve,reject) => {
        resolve(44);
    })

    const p4 = Promise.race([p1,p2,p3])

    p4.then((value) => {
        console.log(value);      //打印43
    })
场景3
    const p1 = new Promise((resolve,reject) => {
        setTimeout(()=>{resolve(42)},1000);
    });

    const p2 = new Promise((resolve,reject) => {
        reject(43);
    })

    p2.catch((value) => {
        console.log("erro")
    })

    const p3 = new Promise((resolve,reject) => {
        resolve(44);
    })

    const p4 = Promise.race([p1,p2,p3])

    p4.catch((value) => {
        console.log(value)      //43
    })

初步实现promise

构造函数

const MyPromise = function(execut){
    const self = this;
    //定义promise的状态、resolve所传递的数据、完成任务队列、拒绝任务队列。
    self.state = "pending";
    self.value = "undefined";
    self.onfulfilled = [];
    self.onrejected = [];

    //resolve方法
    const resolve = (value) =>{
        setTimeout(() => {
            self.value = value ;
            self.state = "fulfilled";
            self.onfulfilled.forEach(func=>func(value))
        })
    };

    //reject方法
    const reject = (value) =>{
        setTimeout(() => {
            self.value = value ;
            self.state = "rejected";
            self.onrejected.forEach(func=>func(value));
        })
    }

    //执行传入的自执行函数
    execut(resolve,reject);

};

then方法

MyPromise.prototype.then =  function(execut1,execut2){
    
    const self = this;
    //事件处理程序必须初始化为函数
    const onfulfilled = typeof execut1 === "function" ? execut1 : value => value;
    const onrejected = typeof execut2 === "function" ? execut2 : value => value;

    //then()需返回promise
    return new Promise((resolve,reject) => {

        //状态为fulfilled时
        if(self.state === "fulfilled"){ 
            //执行成功完成处理程序并获取返回值
            const result = onfulfilled(self.value);

            //返回值为promise时,执行完返回的promise,在回到后续链式调用。
            if(result instanceof MyPromise){
                result.then(resolve,reject);
            }
            else
                resolve(result);   //完成当前promise异步任务,才能进行后续链式调用。
        }

        //状态为rejected时
        else if(self.state === "rejected"){
            const result = onrejected(self.value);
            if(result instanceof MyPromise){
                result.then(resove,reject);
            }else
                reject(result);
        }

        //状态为pending时
        else {

            //状态为pending时,promise内异步队列还未执行,直接向其添加任务以备执行。
            self.onfulfilled.push(function(){
                const result = onfulfilled(self.value);
                if(result instanceof MyPromise){
                    result.then(resolve,reject);
                }
                else
                    resolve(result)
            })

            self.onrejected.push(function(onrejected){
                const result = onrejected(self.value);
                if(result instanceof MyPromise){
                    result.then(resove,reject);
                }else
                    reject(result);
            });
        }
    })
}

来源
《深入理解ES6》
刘小夕promise源码实现

你可能感兴趣的:(promise总结)