当面试官问 promise 的时候,他们希望听到什么(一)

2023-05-16

基础知识 

1、同步回调和异步回调的区别

同步回调: 
    理解: 立即执行, 完全执行完了才结束, 不会放入回调队列中
    例子: 数组遍历相关的回调函数 / Promise 的 executor 执行器函数
异步回调: 
    理解: 不会立即执行, 会放入回调队列中将来执行
    例子: 定时器回调 / ajax 回调 / Promise 的成功 | 失败的回调 

2、JS 中的 Error 相关知识

1、错误的类型
    Error:所有错误的父类型
    ReferenceError:引用的变量不存在
    TypeError:数据类型不正确的错误
    RangeError:数据值不在其所允许的范围内
    SyntaxError:语法错误
2、错误处理
    捕获错误:try ... catch
    抛出错误:throw error
3、错误对象
    message 属性:错误相关信息
    stack 属性:函数调用栈记录信息

一、promise 的基本理解和使用

1、基本概念

Promise 是异步编程的一种解决方案,是 ES6 中的一种规范。所谓 promise ,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。

从语法上来说,Promise 是一个构造函数 ;从功能上来说,promise 对象用来封装一个异步操作并可以获取其成功/ 失败的结果值。

2、基本特点

  1. 对象的状态不受外界影响。promise 对象代表一个异步值,有三种状态:pending(进行中)、fulfilled(已成功)、rejected(已失败)。只有异步操作的结果可以改变这种状态,其他任何操作都不能改变。
  2. 状态一旦变化,就不再发生改变。状态的变化只有两种:从 pending 变为 fulfilled (又被称为 resolved ),或者从 pending 变为 rejected。无论状态变为成功还是失败, 都会有一个结果数据 。其中,成功的结果数据一般称为 value ,失败的结果数据一般称为 reason

3、基本流程

new 一个 promise 实例对象后,紧接着发生的基本流程如下 :

4、基本使用

    <script>
        /*
        1.  创建一个promise实例,这时为 pending状态,
            构造函数 Promise的参数是执行器函数 executor,一般写成箭头函数的形式
        */ 
        const p = new Promise((resolve, reject) => {
            // 2.在执行器函数中启动异步任务
            setTimeout(() => {
                const start = Date.now()
                if (start % 2) {
                    // 3.如果成功,调用 resolve函数 ,
                    // 状态变为 fulfilled(resolvecd),value为成功的值 'ok'
                    resolve('ok');
                }else{
                    // 4.如果失败,调用 reject函数 ,
                    // 状态变为 rejected,reason为失败的值 'error'
                    reject('error')
                }
            }, 1000)
        })
        /*
         5. 状态变化后,执行then方法,
            如果是成功的状态,则调用第一个函数,否则调用第二个函数,来获取成功或失败的值
        */
        p.then(value =>{
            // 成功的回调函数 onResolved, 得到成功的 vlaue
            console.log('success:' + value)
        },reason =>{
            // 失败的回调函数 onRejected, 得到失败的 reason
            console.log('fail:' + reason)
        })
    </script>

then() 方法的执行结果如下:

二、为什么要使用 promise

1、支持链式调用,解决“ 回调地狱 ”

在 promise 出现之前,解决异步编程的方法是使用传统的回调函数和事件。传统的回调函数会出现“回调地狱”回调函数嵌套调用, 外层回调函数异步执行的结果是嵌套的内层回调执行的条件。

回调地狱:


       request1(function(result1){
           request2(result1,function(result2){
               request3(result2,function(result3){
                //    do something... 
                console.log(result3)
               })
           })
        })

嵌套使用回调函数,还有以下的弊端:

  • 代码臃肿。
  • 可读性差。
  • 耦合度过高,可维护性差。
  • 代码复用性差。
  • 容易滋生 bug。
  • 只能在回调里处理异常。

解决方案:可以使用 promise 链式调用的方式解决该问题。

request1.then(result =>{
      return request2(result)
}).then(newResult =>{
      return request3(newResult)
})

2、指定回调函数的方式更加灵活  

传统的方式,必须在启动异步任务前指定回调函数,使用 promise 后,启动异步任务后,返回promise 对象,再给这个对象绑定回调函数

三、promise 有什么弊端

Promise 解决了传统 callback 函数导致的“回调地狱”问题,但它的语法,导致了它纵向发展形成了回调链,在业务比较复杂庞大时,这种写法也不简介方便。
解决方案:使用 async await

async await 也是异步编程的一种方案,它遵循的是 Genarator 函数的语法糖,有内置的执行器函数,不需要额外调用,可以自动执行并输出结果,返回一个 promise 对象。

async await 是基于 promise 实现的,是改良版的 promise ,不能用于普通的回调函数。

四、promise 有哪些 API

1、Promise 构造函数: Promise (excutor) {}

  • executor 函数: 执行器 (resolve, reject) => {}
  • resolve 函数: 内部定义成功时我们调用的函数 value => {}
  • reject 函数: 内部定义失败时我们调用的函数 reason => {}
  • 说明: executor 会在 Promise 内部立即同步调用,异步操作在执行器中执行

2、Promise.prototype.then 方法: (onResolved, onRejected) => {}

  • onResolved 函数: 成功的回调函数 (value) => {}
  • onRejected 函数: 失败的回调函数 (reason) => {}
  • 说明: 指定用于得到成功 value 的成功回调和用于得到失败 reason 的失败回调
  • 返回一个新的 promise 对象

3、Promise.prototype.catch 方法: (onRejected) => {}

  • onRejected 函数: 失败的回调函数 ( reason ) => {} 
  • 说明: then() 的语法糖, 相当于: then( undefined ,  onRejected )

4、Promise.resolve 方法: (value) => {}

  • value: 成功的数据或 promise 对象
  • 说明: 返回一个成功/失败的 promise 对象

5、Promise.reject 方法: (reason) => {}

  • reason: 失败的原因
  • 说明: 返回一个失败的 promise 对象

6、Promise.all 方法: (promises) => {}

  • promises: 包含 n promise 的数组
  • 说明: 返回一个新的 promise, 只有所有的 promise 都成功才返回一个成功的 promise , 只要有一个失败就直接失败,返回一个失败的 promise

7、Promise.race 方法: (promises) => {}

  • promises: 包含 n promise 的数组
  • 说明: 返回一个新的 promise, 第一个完成的 promise 的结果状态就是最终的结果状态

五、关键问题

1、promise 状态什么时候发生变化

  • 调用 resolve(value):当前是 pending 状态,就变为 resolved(即 fulfilled )
  • 调用 reject(reason):当前是 pending 状态,就变为 rejected
  • 抛出异常 throw ERROR :当前是 pending 状态,就变为 rejected

2、一个 promise 指定多个成功/失败回调函数, 都会调用吗

当 promise  改变为对应的状态时,会调用相应的回调函数。

3、改变 promise 状态和指定回调函数谁先谁后

  • 都有可能, 正常情况下是先指定回调再改变状态, 但也可以先改状态再指定回调
  • 如何先改状态再指定回调?
  •         ① 在执行器中直接调用 resolve()/reject()
  •         ② 延迟更长时间才调用 then()
  • 什么时候才能得到数据?
  •         ① 如果先指定的回调, 那当状态发生改变时, 回调函数就会调用, 得到数据
  •         ② 如果先改变的状态, 那当指定回调时, 回调函数就会调用, 得到数据

4、promise.then() 返回的新 promise 的结果状态由什么决定

  • 简单表达: then()指定的回调函数执行的结果决定
  • 详细表达:
  •         ① 如果抛出异常, promise 变为 rejected, reason 为抛出的异常
  •         ② 如果返回的是非 promise 的任意值, promise 变为 resolved, value 为返回的值
  •         ③ 如果返回的是另一个新 promise, promise 的结果就会成为新 promise 的结果

5、promise 如何串连多个操作任务

  • promise then()返回一个新的 promise, 可以开成 then()的链式调用
  • 通过 then 的链式调用串连多个同步/异步任务

6、promise 异常传透

  • 当使用 promise then 链式调用时, 可以在最后指定失败的回调,
  • 前面任何操作出了异常, 都会传到最后失败的回调中处理

7. 使用 promise then() 链式调用时, 如何中断链, 不再调用后面的回调函数

  • 办法: 在回调函数中返回一个 pendding 状态的 promise 对象

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

当面试官问 promise 的时候,他们希望听到什么(一) 的相关文章

  • 基本类型与包装(装箱)类型的区别

    Java的类型分为两部分 xff0c 一个是基本类型 xff08 primitive xff09 xff0c 如int double等八种基本数据类型 xff1b 另一个是引用类型 xff08 reference type xff09 xf
  • 学习笔记------关于字符串结束符'\0'、字符串定义方法

    字符串定义方法 有2种方法 xff1a 1 xff09 字符数组 2 xff09 字符指针 初始化 1 xff09 字符数组方式初始化大致3种 xff1a 1 char str 10 61 34 12345 34 或者char str 10
  • 树莓派连接vnc教程

    1 输入 sudo raspi config 进入到系统设置中开启vnc服务 2 进入后选择 Interfacing Options 进入 3 选择 VNC 进入 4 yes 下载软件 xff1a VNC Viewer 5 连接vnc xf
  • ubuntu 22.04设置root密码,与开启sshd服务

    1 sudo passwd root 直接输入两次密码即可完成 2 安装sshd服务 xff1a apt install ssh 3 启动ssh服务 systemctl start sshd 4 设置开机启动 xff1a systemctl
  • Python+Flask+Docker+Vue实现简单的股票数据统计

    闲暇时间实现了一个简单的股票数据统计功能 数据是从网上爬下来的 xff0c 页面支持按照股票名称 股票代码 股票类型 股价 市值等搜索并展示在下方列表 除了股票的基本信息以外 xff0c 还会显示其他炒股软件上不会展示的信息如流动比率 速动
  • [2020-07-23]备战考博的一点点经历

    首先声明 xff0c 博主只是个普通人 xff0c 不是北清复交那种天才选手 xff0c 本硕都是普通一本 xff0c 像个不断前进的蜗牛一样 xff0c 好不容易还有继续往上爬的机会 xff0c 所以博主只会从一个普通学生的视角去讲自己的
  • 遇见Java

    Java是一门面向对象的编程语言 xff0c 不仅吸收了C 43 43 语言的各种优点 xff0c 还摒弃了C 43 43 里难以理解的多继承 指针等概念 xff0c 因此Java语言具有功能强大和简单易用两个特征 Java语言作为静态面向
  • STM32F103移植FreeRTOS警告记录

    1 xff1a 新建MDK工程 xff0c 选择文件存放路径 xff0c 选择芯片型号 xff0c 创建一个USER文件 xff0c 复制自动创建的文件到USER文件中 xff0c 关闭程序 创建一个OBJ目标文件夹 xff0c 打开软件选
  • tensorflow实现简单的卷积神经网络

    1 卷积神经网络 xff08 Convolutional Neural Network xff0c CNN xff09 优点 xff1a xff08 1 xff09 直接使用图像的原始像素作为输入 xff0c 不必先使用SIFT等算法提取特
  • zabbix4.0学习八:JMX有能监控哪些监控项详说

    zabbix4 0学习八 xff1a JMX有能监控哪些监控项详说 文章目录 zabbix4 0学习八 xff1a JMX有能监控哪些监控项详说 前言远程连接tomcat远程连接java 前言 在使用jmx监控tomcat时一直好奇MBea
  • 排序算法之冒泡排序、选择排序、插入排序的区别与联系

    冒泡排序 xff08 1 xff09 算法 xff1a 假如有N项数据 第一趟 xff0c 将首项与第二项比较 xff0c 较小者放在前面 xff0c 较大者放后面 xff0c 然后比较第二项和第三项 xff0c 依次进行 xff0c 第一
  • 排序算法之快速排序算法

    核心思想 xff1a xff08 1 xff09 要排序的一组数据中取一个数为 基准数 xff08 2 xff09 通过一趟排序将要排序的数据分割成独立的两部分 xff0c 其中左边的数据都比 基准数 小 xff0c 右边的数据都比 基准数
  • 数据结构之树知识汇总——思维导图

  • Linux基础学习与VMWare的安装和使用

    一 Linux入门概述 1 1 概述 Linux内核最初只是由芬兰人林纳斯 托瓦兹 xff08 Linus Torvalds xff09 在赫尔辛基大学上学时出于个人爱好而编写的 Linux是一套免费使用和自由传播的类Unix操作系统 xf
  • OJ刷题之1035:列车长的烦恼

    OJ刷题之1035 xff1a 列车长的烦恼 1 题目以及要求2 题目解析3 代码思路 1 题目以及要求 description John是个小列车站的站长 xff0c 每次列车在这里重新编组时他就很烦恼 因为站上只有一个人字形的编组轨道
  • python数据可视化之matplotlib学习

    python数据可视化 xff1a Matplotlib的scatter函数详解 scatter 函数参数详解 xff1a scatter x y s 61 None c 61 None marker 61 None cmap 61 Non
  • Ubuntu16.04使用sudo apt-get install ,报错E: 无法获得锁 /var/lib/dpkg/lock-frontend - open (11: 资源暂时不可用)

    Ubuntu16 04 使用sudo apt get install git 安装git服务器 xff0c 结果出现下面的错误 E 无法获得锁 var lib dpkg lock frontend open 11 资源暂时不可用 E Una
  • python之机器学习案例实战:信用卡欺诈异常值检测

    案例背景 xff1a 有些人利用信用卡进行诈骗活动 xff0c 如何根据用户的行为 xff0c 来判断该用户的信用卡账单是否属于欺诈呢 xff1f 想获取数据集请点此处 在这个数据集中 xff0c 由于原始的用户数据具有一定的隐私 xff0
  • 信用卡欺诈检测数据集

    1 数据集简介 信用卡欺诈检测 xff0c 即异常检测 xff0c 指的是信用卡被盗刷的情况检测 该数据集中收集的是2013年9月欧洲人使用信用卡在两天内产生的交易数据 xff0c 其中284807笔交易中有492笔被盗刷 是机器学习与Py
  • 上手Vue:深度理解computed、watch及其区别

    computed xff08 计算属性 xff09 与watch xff08 侦听器 xff09 xff0c 是Vue中常用的属性 xff0c 那么什么时候该如何computed xff0c 什么时候该使用watch呢 xff1f 1 co

随机推荐