第二十八章 Promise

94 阅读5分钟

一、认识Promise

let p1 = new Promise(function (resolve, reject) {
            //resolve,reject是两个函数体,Promise给的
            //resolve、reject   都不执行 p1 会处在  pending(等待)    
            //reject(777); 把p1 由 pending 变成了 rejected(失败态)
            //resolve(888);  把p1 由 pending 变成了 fulfilled/resolved(成功态)
            //p1一旦变成了rejected或fulfilled 那么就不会再去改变了
  console.log(resolve, reject);
});

如上述代码所示,p1为Promise的实例;

1、实例会有三种状态:

  • 原始状态pending;
  • 成功态fulfilled/resloved;
  • 失败态rejected;

2、实例的状态只能由pending变成fulfilled/resloved 或者 rejected;fulfilled与rejected不能相互转换(成功态失败态谁先出来就是谁,不能覆盖或者改变)。

  • 该回调函数报错的时候,实例的状态也会变成rejected(不常见)

二、Promise实例方法

1、实例.then()

  • 代码:实例.then(回调函数1,回调函数2)
  • 回调函数1:
    执行:当实例的状态由pending变成fulfilled的时候
    实参:resolve执行的时候传递的第一个参数
  • 回调函数2(可不写):
    执行:当实例的状态由pending变成rejected的时候
    实参:rejected执行的时候传递的第一个参数(或者错误信息)
    • 执行的时候可以把reject的错误信息融掉,错误信息不显示在控制(处理异步)
    • try{}catch(err){ console.log(err) } (处理同步)
p1.then(function then的回调函数1(data){
        console.log(111,data);//   
},function then的回调函数2(err){
        console.log("err",err);       
});

2、实例.then()... .catch()

  • 代码:... .catch(err=>{ console.log() })
  • 回调函数:
    执行:在上边的实例代码执行到此出现失败态的时候
    注意:兜底的错误是没有被上边兜住的错误
let p1 = new Promise(function(reslove,reject){
        console.log(qqq);

    });
     p1.then(data=>{
        console.log(111,data);
    }).then(data=>{
        console.log(222,data);
    }).catch(function(err2){
       
        console.log(333,err2);
    });

3、实例.then().then()

  • 后边then执行时机:看上一个then对应回调函数执行的成功态或者失败态
  • 后边then执行参数:由上一个then中回调函数的返回值决定的

4、.finally()

  • 对应的回调会在最后不管是成功还是是失败了,都会走finally
  • 对应的回调函数没有参数
  let p1 = new Promise((reslove,reject)=>{
        reslove(888);
        // reject(777);
    });
    p1.then(data1=>{
        console.log('data1',data1);
        return 12345            //为下一个then传实参
    },err1=>{
        console.log('err1',err1); 
        // throw new Error('666');     //主动抛错
               
    }).then(data2=>{
        console.log('data2',data2);
        return 123345
    },err2=>{
        console.log('err2',err2);
    }).finally((res)=>{
        console.log('最后',res);
    });

三、Promise静态方法

1、创造一个成功态的实例

  • 代码:Promise.resolve()
let p2 = Promise.resolve(2424)  //直接创造一个成功态的实例
    p2.then(data=>{
        console.log('data',data);
    })

2、创造一个失败态的实例

  • 代码:Promise.rejected()
et p3 = Promise.reject(777)   //直接创造一个失败态的实例
    p3.then(data3=>{
        console.log('data3',data3);  
    },err3=>{
        console.log('err3',err3);     
    })

3、all使用

  • 代码:Promise.all([p1,p2,p3])
  • 返回值:一个Promise实例
    返回实例如果数组里边的所有实例都变成成功态之后,返回的实例才能变成成功态;数组里边的实例只要有一个变成失败态,返回的那个实例就会变成失败态
let p1 = new Promise((reslove, reject) => {
        setTimeout(() => {
            reslove(111)
            // reject(11)
        }, 3000);
    })
    let p2 = new Promise((reslove, reject) => {
        setTimeout(() => {
            reslove(222)
            // reject(22)
        }, 5000);
    })
    let p3 = new Promise((reslove, reject) => {
        setTimeout(() => {
            reslove(333)
        }, 7000);
    })
    -------------------
      Promise.all([p2,p1,p3]).then(data=>{
        //data是个数组,位置跟all参数位置保持一致
        console.log(('data',data));
    }).catch(err=>{
        console.log('err',err);
    });
//所有的实例都成功之后才会执行后边的成功态,一旦有一个实例为失败态,则返回错误(在没有兜底的情况下),由兜底则返回兜底的。

4、race(速度)

  • 代码:Promise.race([p1,p2,p3])
  • 返回值:Promise的一个实例
  • 参数:传递的参数是一个数组,后边的then是给第一个完成状态变化的那个实例准备的
  • 注意:只要有一个实例完成状态变化,后边的then就是给这个实例准备的

5、Promise实现回调函数(获取数据)

//JQ实现
function getData() {
        let p1 = new Promise((res, rej) => {
            $.get('./data.json', function (data) {
                res(data);
            });
        })
        return p1
    }
    getData().then(data => {
        console.log(data);
    })
//Ajax实现
function getData() {
        let p1 = new Promise((res, rej) => {
            let xhr = new XMLHttpRequest;
            xhr.open("get", "./data.json", false);
            xhr.onreadystatechange = function () {
                if (xhr.readyState == 4 && xhr.status == 200) {
                    let data = JSON.parse(xhr.response);
                    res(data);
                };
            };
            xhr.send();
        });
        return p1
    };

    getData().then(data => {
        console.log(data);
    })

6、async await

  • 功能:让写异步更像是再写同步
  • async await 的语法:是为了让编写异步代码更像是在编写同步编码!!!(重要的东西重复)
  • async await 需要结合Promise语法才能起作用
async function render(){
  let data = await getData()
  console.log(111,data);
}

7、Promise总结

  • Promise的设计是为了方便异步开发的
  • 实例有三个状态:pending fulfilled/resloved rejected
    状态只能由pending变成其他两个,只能变一次\
    • pending--》fulfilled reslove执行\
    • pending--》rejected reject执行
  • 实例.then(成功态的回调,失败态的回调)
  • 实例.catch(失败态的回调)
    作用:兜底错误
  • 实例.finally()
    作用:无论前边失败态还是成功态或者出错都会执行,并且是报错之前的最后一次执行。

8、动画

  • CSS方法:
    • transition: all 1s ease-in-out 过渡
    • 参数:第一个为变化尺寸,第二个元素为过渡时间,第三个元素为变化速度控制
    • animation: qqq 1s 1s infinite @keyframes qqq{ 0%{ transform: rotate(0deg) translateX(400px); }

50%{ transform: rotate(225deg) translateX(600px); }

100%{ transform: rotate(0deg) translateX(0); } }

  • 参数:第一个动画名字,第二个为运动时间,第三个为延时时间,第四个为运动次数(infinite是一直重复运动)