• Js手写面试题5-Promise


    Promise

    ❓有任何疑问都可以私信我解答

    ⚡️仓库地址:https://gitee.com/super_li_yu/jsexamdemo/tree/master/JavaScript/promise

    😛建议关注,持续更新。

    ✒️主要内容:Promise

    Promise是一门是在ES6里提出的新技术,是JS在异步编程的一种解决方案,可以支持链式调用,可以解决地狱问题指定回调的问题更加灵活。

    Promise成功会调用resovle中,失败会调用reject。then里面会包裹两个函数体,第一个函数体放成功的逻辑,第二个函数体放失败的逻辑。

    1.原理

    1.Promise的状态

    • pending 进行中
    • resolved/fullfilled 成功
    • rejected 失败

    2.Promise 对象的值

    实例对象中的另外一个属性:[PromiseResult]

    保存着对象[成功/失败]的结果

    • resolve
    • reject

    3.Promise的工作流程

    请添加图片描述

    4.Promise相关的API

    1. Promise构造函数:Promise(excutor){}
      • excutor函数:执行器。(resolve,reject)=>{}
      • resolve函数:内部定义成功时我们调用的函数value=>{}
      • reject函数:内部定义的失败时候会调用函数reson=>{}
    说明

    excutor会在Promise内部立即同步调用,异步操作在执行器中执行。

    1. Promise.prototype.then方法:(onResolved,onRejected)=>{}
      • onResolved函数:成功的回调函数(value)=>{}
      • onReject函数:失败的回调(reson)=>{}
    说明

    指定用于得到成功的value的成功回调和用于得到失败的reson的失败回调返回一个新的Promise对象

    1. Promise.prototype.catch方法:(onRejected)=>{}
      • onRejected函数:失败的回调函数(reson)=>{}
    2. Promise.resolve方法:(value)=>{}
      • value成功的数据或者promise对象
    说明

    返回一个成功/失败的Promise对象

    1.如果传入的的参数为非promise类型的对象,则返回的结果为成功promise对象

    2.如果传入的参数为promise对象,则参数的结果决定了resolve的结果

    1. Promise.reject方法:(reson)=>{}
      • reson:失败的原因
    说明

    返回一个失败的Promise对象

    无论你传入什么数值,都是失败的对象

    1. Promise.all方法:(Promise)=>{}
      • Promise:包含n个Promise对象的数组
    说明

    返回一个新的Promise,只有所有的Promise都成功才成功,只要有一个失败就直接失败

    • 如果都成功,就返回一个数组,里面是返回成功的对象.

    • 如果有一个失败,就返回该失败的结果.

    1. Promise.race方法:(Promises)=>{}
      • promise:包含多个
    说明

    返回一个新的Promise,第一个完成的Promise的结果状态就是最终的结果状态

    2.问题

    1.Promise状态的改变

    请添加图片描述

    2.改变Promise状态和指定回调函数谁先谁后?

    then方法先执行还是改变状态先执行.

    1. 都有可能正常情况下是先指定回调再改变状态,但也可以先改变状态再指定回调
    2. 如何先改变状态再指定回调?
      • 再执行器中直接调用resolev()/reject()
      • 延迟更长时间才调用then()
    3. 什么时候才能得到数据?
      • 如果先指定回调,那当状态发生改变时,回调函数就会调用,得到数据.
      • 如果先改变的状态,那当指定回调时,回调函数就会调用,得到数据.
    4. promise.then()返回的新promise的结果状态由什么决定?
      • 简单表达:由then()指定的回调函数执行的结果决定
      • 如果返回的是非promise的任意值,新promise变成

    3.Promise的异常穿透

    1. 当使用Promise的then链式调用后,可以在最后指定失败的回调
    2. 当前任何操作出现了异常,都会传到最后失败的回调中处理

    这块应用场景最多的还是在链式调用的最后,使用.catch来捕捉错误.中间出现的任何错误,都可以到最后进行捕获

    let p = new Promise((resolve, reject) => {
      setTimeout(() => {
        // resolve('ok');
        reject('出错了')
      }, 1000)
    })
    
    
    p.then(value => {
      console.log(111);
    }).then(value => {
      console.log(222);  //success
    }).then(value => {
      console.log(333); //undefined
    }).catch(reson => {
      console.warn(reson);
    })
    

    4.如何中断Promise链条

    只要我们给消息队列中想要中断的位置添加一个状态为pedding(进行中)的Promise就可以了。

    let p = new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve('ok')
      }, 1000)
    });
    
    p.then(value => {
      console.log(111)
      //返回一个padding状态的promise的回调对象
      return new Promise(() => { })
    }).then(value => {
      console.log(222);
    }).then(value => {
      console.log(333);
    }).catch(reson => {
      console.log(reson);
    })
    

    这样控制台只会输出111,后面的222,333,就不会再输出了。

    5.手写一个promise

    这块内容在代码仓库里哦

    代码

    抽奖函数

    DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>抽奖系统title>
    head>
    <body>
      <button id="btn">点击抽奖button>
    body>
    html>
    
    
    <script>
      //生成随机函数
      function rand(m,n){
        return Math.ceil(Math.random() * (n-m+1)) + m-1;
      }
    
      /**
       * 点击按钮,2s后显示是否中奖(30%概率)
       * 中奖弹出
       * 未中奖弹出  再次努力
      */
    
      //原生js实现
    //  const btn = document.querySelector("#btn");
    //   btn.addEventListener('click',function(){
    //     //定时器
    //     setTimeout(()=>{
    //       //30%  1-100   1-30
    //       let n = rand(1,100)
    //       if(n <= 30){
    //         alert('中奖')
    //       }else{
    //         alert('没中奖')
    //       }
    //     },1000)
    //   })
    
    
    
    
    // Promise实现
    /**
     * resolve 解决  函数类型的数据
     * rejet 拒绝    函数类型的数据
    */
    const btn = document.querySelector("#btn");
    btn.addEventListener('click',function(){
      const p = new Promise((resove,reject)=>{
      setTimeout(()=>{
      //30%  1-100   1-30
      let n = rand(1,100)
      if(n <= 30){
        resove(n); //调用完成后,可以将Promise对象的状态设置为成功
      }else{
        reject(n); //调用完成后,可以将Promise对象的状态设置为失败
      }
      },1000)
    })
    
    //调用then方法
    p.then((n)=>{
      alert(`中奖号为${n}`);
    },(n)=>{
      alert(`失败,号码为${n}`);
    })
    });
    
    
    script>
    

    其他源码看仓库即可

  • 相关阅读:
    Jackson ObjectNode JsonNode --> FastJson JSONObject
    【深入理解Kotlin协程】使用Job控制协程的生命周期
    图片懒加载实现方案
    计算机毕设(附源码)JAVA-SSM基于技术的高校学生勤工俭学管理系统的设计与开发
    多线程编程模式-Producer-consumer
    Android中的KeyEvent详解
    PROFINET 模拟器使用教程
    JAVA之Mysql应用|记一次通过mysql表中的三个字段对应一个前端组合状态字段查询场景的解决方案
    SpringBoot SpringBoot 开发实用篇 3 测试 3.7 匹配响应体【JSON】
    pyqt的QWidgetList如何多选?如何按下Ctrl多选?
  • 原文地址:https://blog.csdn.net/liyuchenii/article/details/127098433