Promise语法

Promise概述

Promise对象具有三种状态:

pending(进行中)

resolved(已成功)

rejected(已失败)

promise内部会封装一个异步操作,当异步完成时,promise的状态就会发生改变,如果异步操作是成功的,状态变为resolved,如果异步操作是失败的,状态会变为rejected

当promise的状态发生改变,让promise的回调函数进行回调队列(微队列),等待执行。

没有 promise 的时候,异步操作完成直接让自己的回调函数进入回调队列等待执行;有了 promise 的封装,异步操作执行完毕,改变 promise 的状态,promise 状态改变让 promise 的回调函数进入回调队列等待执行。所以,promise 就是中间商!

promise基本语法

①使用Promise构造函数创建promise对象

let p=new Promise(()=>{});

p就是创建的promise对象,初始状态是pending

Promise参数必须是一个回调函数

②修改promise对象的状态

//需要给Promise的回调函数传参
let p = new Promise((resolve,reject)=>{
   resolve();//将promise对象状态变为resolved(fulfilled)
});

promise 对象的状态一旦改变,就不能在改变了。

Promise构造函数的参数是回调函数,是同步执行的,实例化过程就执行了

通过then方法给promise对象指定的回调函数是异步执行的,当promise的状态发生改变,这里的回调函数进入回调队列等待执行。

③指定promise对象的回调函数

let p=new Promsie((resolve,reject)=>{
   //resolve和reject不论先调用谁,调用之后的状态都不会再发生改变
   //调用resolve,把状态改为resolved,该参数会传递给then第一个回调函数
   resolve([4,6,34,3]);
   //调用reject把状态改为rejected,该参数回传给then的第二个回调函数
   reject('连接超时...');
});

p.then((value)=>{
   console.log(value);//[4,6,34,3]
},reason=>{
   console.log(reason);//连接超时...
})

可以给promise指定两个回调函数,如果promise对象的状态是resolved,调用第一个回调函数,如果promise的状态是rejected,调用第二个回调函数;

Promise构造函数的回调函数中,调用resolve和reject的时候可以传递参数,promise对象的回调函数可以接收

Promise实例的方法

1. Promise.prototype.then()

①参数

then方法可以指定两个函数,都是回调函数,promise状态如果

是成功的调用第一个参数,promise对象如果是失败的,调用第二个参数

②返回值

then()方法一定会返回promise对象,所以then方法支持链式调用

then()方法返回值规则如下:

  1. 如果回调函数没有返回值,then()返回一个成功的promise对象,值是undefined。

  2. 如果回调函数指定返回值(且不是promise对象),then方法返回一个成功状态的promise对象,值是回调函数的返回值。

  3. 如果回调函数中抛出错误,then方法返回一个失败状态的promise对象,失败的reason是错误信息

  4. 如果回调函数是一个promise对象,返回值就是此promise对象

2.catch方法

①参数

参数指定一个回调函数,promise对象的状态变为失败的时候会调用

②then和catch可以配合使用

let p=new Promise((resolve,reject)=>{
   reject('故意出错');
});

p.then(()=>{
   console.log('成功');
}).catch(reason=>{
   console.log('出错',reason);
})

③异常穿透

使用 then 进行链式调用的时候,可以只给then指定成功的回调函数,最后通过 catch 兜底,不论哪一步出现异常(状态变为失败),最终都会穿透到 catch ,执行它的回调函数。

  function setTimeoutPromise(delay, value) {
     // 创建 promise 对象并返回
     return new Promise((resolve, reject) => {
         setTimeout(resolve, delay, value);
    });
}

setTimeoutPromise(2000).then(() => {
   //取 0 -9 之间随机数
   let rand1 = Math.floor(Math.random() * 10);
   console.log(rand1);
   a; // 异常语法
   // 返回一个 promise 对象
   return setTimeoutPromise(3000, rand1);
}).then(value => {
   // 取随机数 + value
   let rand2 = Math.floor(Math.random() * 10) + value;
   console.log(rand2);
   // 返回一个 promise 对象

   return setTimeoutPromise(1000, rand2);

}).then(value => {
   // 取随机数 + value
   let rand3 = Math.floor(Math.random() * 10) + value;
   console.log(rand3);
}).catch(reason => {
   console.log('错误:', reason);
})

3.finally

接收一个回调函数作为参数,只要promise状态改变,回调函数就调用

Promise构造函数本身方法

1.Promise.resolve()

①功能

返回一个promise对象,可以用来快速创建一个promise对象

②根据参数不同返回的promise也不同

  1. 如果不给参数,返回一个成功状态的promise对象,值是undefined

  2. 如果给一个值作为参数(不是promise对象也不是thenable对象),返回一个成功状态的 promie 对象,值是参数。

  3. 如果参数是个 promise 对象,直接把这个 promise 对象作为返回值。

  4. 如果参数是一个thenable对象,方法内部会根据then方法创建一个有promise对象并返回

    具有then方法的对象就是thenable对象

    var obj={
       then(resolve,reject){
           reject('老子错了');
      }
    };
    let p4=Promise.resolve(obj);
    // 执行 resolve 方法的时候,内部实例化 Promise 构造函数,把 then 方法作为参数

     

2 Promise.reject()

没有 Promise.resolve 那么复杂,就返回一个失败状态的 promie 对象,参数不论是什么数据都会作为返回的promise对象失败原因;没有参数失败原因就是undefined。

3 Promise.all()

可以把多个promise对象整合成一个promise对象并返回

参数是一个数组或者其他可遍历对象,成员都是promise对象(不是promise对象的会自动使用Promise.resolve()创建为promise对象)

  1. 如果传入的所有的promise对象都是成功状态,则返回的promise对象会是所有promise对象的值组成的数组

  2. 一旦有一个 promise 对象变为失败状态,返回的 promise 对象立即变为失败状态!

Promise 的优势

  1. 回调函数设置方式更加灵活,可以设置多个,可以再任何时刻设置回调函数。

  2. then 方法的链式调用,有效解决回调地狱问题 (回调地狱:回调函数内部嵌套回调函数)

宏队列和微队列

事件轮询机制中,回调队列有两个,分别是宏对列和微队列。

定时器的回调函数、DOM事件的回调函数、Ajax的回调函数会进入宏队列。

promise对象的回调函数进入微队列。

当执行栈空了之后,会先把微队列中的回调函数以此取出来执行,等微队列都执行完毕了,才从宏队列中依次取出回调函数执行。

posted @ 2020-11-24 21:27  新成  阅读(449)  评论(0编辑  收藏  举报