admin 管理员组

文章数量: 887031

必备

必备-3.Promise详细解读

Promise是ES6新增的一个内置类(不兼容IE浏览器)

  • 如果需要兼容,则自己手写Promise(PromisesA+)【有一个模块实现了Promise的封装@babel/polyfill】

Promise是什么?

  • Promise是一种设计模式(承诺者模式

Promise的作用是什么 ?

  • Promise是为了管理异步编程代码,解决异步编程中的回调地狱问题

Promise的组成需要什么?

  • @1立承诺:要干的事情、状态(成功、失败)、成功对应要做什么、失败对应要做什么
  • @2 后续要干的事情出结果,按照之前承诺的去履行就行

Promise的特点?

  • @1创建:设立一个承诺其实就是创建Promise构造函数的一个实例

    • let p=new Promise([executor]);//executor必须是一个函数,不是函数则报错:Promise resolver xxx is not a function;
  • @2在new Promise时,会把传递的executor函数立即执行;

    • executor】被称为可执行函数,在这个函数中我们一般管理异步编程的的代码。
    • executor】函数中有两个形参resolve&reject,参数类型是新的函数
      • resolve([value]):让实例状态变为“fulfilled”,值是[value]
      • reject([reason]):让实例状态变为“rejected”,值是[reason]
      • 状态一旦从"pending“被改为”fulfilled“或者”rejected"则不能再修改了
      • exector函数在执行过程中,如果代码执行报错了,则实例的状态也是rejected,值是报错原因
      • exector函数中如果存在异步代码,不会等待异步代码,先执行后面的以及执行函数之外的同步代码
      • p1.then/catch/finally:都是异步的
  • @3 p是创建的promise实例:

    • 私有属性:

      • [[PromiseState]]:实例状态: “pending”、 “fulfilled”、 “rejected”
      • [[PromiseResult]]:实例的结果:“undefined”、”成功的结果(value)“、”失败的原因(reason)“
    • 所属类原型上的公共方法:

      • then([onfulfilled],[onrejected]):

        • [onfulfilled]:实例状态成功执行的函数

        • [onrejected]:实例状态失败执行的函数

      • catch([onrejected]):只有实例状态失败时执行的函数

      • finally([onfinally]):不管状态是成功还是失败,都执行的函数

  • 学习Promise主要是在学习:如何创建promise实例,以及如何去修改实例状态和结果,只有这样才能知道then中的onfulfilled/onrejected谁执行,传递的值value/reason是啥。

Promise实例p的公有方法及用法?

  • then([onfulfilled],[onrejected]):

    • [onfulfilled]:实例状态成功执行的函数

    • [onrejected]:实例状态失败执行的函数

    •         let p=new Promise((resolve,reject)=>{resolve("oky");reject("no");})p.then((value)=>{console.log("成功",value)},//成功状态执行--》"成功" oky(reason)=>{console.log("失败",reason)})//失败状态执行--》"失败" no
      
    • 每一个实例都可以执行多次then方法,用于指定成功或失败干的事情,当状态一旦确定,之前承诺的多个方法都会一次执行!,这不是then链,只是同一个实例执行多次then

  • catch([onrejected]):只有实例状态失败时执行的函数

    • .catch([onrejected])等价于.then([null],[onrejected])
  • finally([onfinally]):不管状态是成功还是失败,都执行的函数

创建Promise实例的几种方案?

  • @1 new Promise([executor(resolve,rejecet)])
    • executor函数执行报错:则实例的状态rejected,实例的结果是报错原因
    • resolve([value]): 实例状态fulfiled,实例的结果是[value]
    • rejecet([reason]): 实例状态rejected,实例的结果是[reason]
  • @2 执行Promise对象中的某些静态私有属性方法,也可以创造promise实例
    • Promise.resolve([value]):立即创建一个状态是fulfilled,值是[value]的实例
    • Promise.reject([value]):立即创建一个状态是rejected,值是[reason]的实例
  • @3 执行p1.then([onfulfilled],[onrejected]))/p1.catch()方法,会返回一个全新的Promise实例【p2】
    • 不论是执行[onfulflled],还是[onreiected],【p2】状态都符合以下几种情况:
      • 首先看方法执行是否报错,如果报错,则p2的状态是rejected,值是报错原因
      • 如果不报错,再看方法执行的返回值【x】
        • 如果【x】不是Promise实例,则p2的状态是fulfilled,值是x
        • 如果【x】是一个Promise实例,则p2的状态和值与x保持一致
          • return Promise.reject(value/10);—》p2状态为rejected
          • return Promise.resolve(value/10);–》p2状态为fulfilled
  • @4 基于Promise.all/race/any([promises])也会返回一个新的promise实例【@p】
    • [promises]包含0到多个promise实例集合的数组
    • Promise.all([promises]):与运算
      • 所有实例都成功,@p才成功,[值:按照数组的顺序,依次存储每个实例的结果]
      • 只要有一个实例失败,@p就失败,[值:本次失败的原因]
    • Promise.any([promises]):或运算
      • 集合中只要一个实例成功,则@p就是成功的,[值:这个成功的结果]
      • 集合中如果所有实例失败,则@P才是失败的,[值:失败的原因的数组]
    • Promise.race([promises]):竞赛
      • 比赛,集合中那个实例先返回结果,则以谁的为主[值:成功的结果或失败的原因]
    • 如果集合中的某一项不是promise实例,则会默认把其编程状态为成功,值是这个值的promise实例

什么是then链?

  • THEN链:每一次执行then方法都会返回一个新的promise实例,所以可以继续执行then…
    • Then中传递的[onfulfilled]或[onrejected]可以不设置
      • .then(null,[onrejected])
      • .then([onfulfilled])
    • then链的顺延/穿透机制”:[onfulfilled]或者[onrejected]如果不设置,则应该让其顺延到下一个THEN中相同相状态下要执行的方法
    • then链resolved、rejected顺延的原理:
      • .then(null,[onrejected])---->.then((value=>{return value}),[onrejected])
      • .then([onfulfilled])------------>.then([onfulfilled],reason=>{throw reason;})
      • .then(null,[onrejected])等价于:.catch([onrejected])

AJAX如何使用

项目中所有的ajax请求都是异步的

  • 后期项目中,所有ajax的异步请求都需要基于promise管理—>axios:基于promise封装的ajax库
  • 我们还可以基于Promise+Generator的语法糖 async/await 管理串行

ajax的并行和串行?

  • ajax的串行:多个请求之间有依赖,上一个请求完成,才能发送下一个请求【一般会把上一个请求获取的信息作为参数,然后再发送到下一个请求】

  • ajax的并行:多个请求之间没有依赖,同时发送多个请求,谁先处理完都可以【一般我们会做一个处理,等待所有请求都成功,再去做一些事情==》基于Promise.all处理即可】

async和await

1.async和await?

async和await的作用:将异步操作变为同步效果

  • 同步:上一个代码成功(resolved),下面的代码才会执行,否则下面的代码永远不会执行

  • 异步:上面的代码报错了(rejected),下面的代码不受影响,继续执行

2.async和await的关系?

  • 可以单独用async,但是await不能单独使用。
  • async的功能:只是简化了function的返回promise实例的,不强大
  • await的功能:await必须结合async使用,await是实现异步操作同步化的关键,很强大

3.async?

  • async修饰符

    • async函数返回值是一个promise实例,相当于then()方法里面的成功或失败函数执行

    • 如果返回的promise实例状态为rejected,控制台中会报错,但是它后续代码仍会执行

    • async修饰符:修饰一个函数,让函数的返回值成为一个promise实例,这样,就可以基于THEN链去处理

    • 用法:

      • async function fn(){reutrn ;//相当于return Promise.resolve();return 10;//相当于return Promise.resolve(10);return Promise.resolve(10);//返回的实例状态为resolved,值为10return Promise.reject("错了");//返回实例状态为rejected,值为“错了”return x;//没有x变量,所以报错,所以返回实例状态为rejected,值为"报的错"}
        

4.不同场景中async函数执行返回的结果是什么?

  • 没有return: 默认返回一个promise实例,状态resolved,值undefiend
  • 代码执行过程中报错:返回一个promise实例,状态rejected,
  • return的x不是promise实例:返回一个promise实例,状态resolved,值x
  • return的是promise类型:返回promise实例,状态依实例而定,值成功的结果或失败的原因
场景返回值类型状态
没有return默认返回一个promise实例resolvedundefiend
执行过程中报错返回一个promise实例rejected报的错
return的x不是promise实例返回一个promise实例resolvedx
return的是promise类型返回一个promise实例resolved/rejected成功的结果/失败原因

5.await?

  • await:等待,我们一般在其后面放promise实例,它会等待实例状态为成功,再去执行"当前上下文中",await下面的代码,【如果状态永远不成功,下面的代码永远不执行】
    • 如果await后面的x不是promise实例:则浏览器默认把其转换为【状态为resloved,值为x
  • await的作用:如果Promise实例管控的是一个异步编程,其实await是在等待异步成功,再执行下面代码,类似于异步改为同步效果

6.Promise实例p中的then、catch、finally方法是什么时候放到等待队列的?

  • 当执行到then/catch/finally方法时,会首先将它放到监听队列(Web API)
    • 如果p实例没有改变状态,那么这些方法永远不会放到等待队列中
    • 当p实例的状态发生改变时,会立即将方法放到等待队列(Event queue)微任务中

7.async和await中的异步体现在哪里?

  • async、await中的异步:并不是说async的整个方法都是异步微任务,而是说async函数中的await后面的代码部分,可以被视为异步微任务,因为只有await结果为resolved的时候,后面的代码才能够被执行,否则,永远不会被执行

8.异步微任务和异步宏任务?

  • 异步微任务7个:
    • async/await
    • requestAnimationFrame[存在争议]
    • Promise中的then/catch/finally方法
    • IntersectionObserver:(交叉观察者)监听我们当前DOM元素与可视窗口的交叉信息
    • MutationObserver:(变异观察者)监听DOM元素改变的
    • queueMicrotask :(队列微任务)可以创建一个异步的微任务
    • process.nextTick:[Node]执行下一个任务或队列
  • 异步宏任务5个:
    • ajax
    • 绑定事件
    • setTimeout/setInterval:定时器
    • setImmdiate[Node的定时器]
    • MessageChannel:消息通知队列(很少用)

本文标签: 必备