面试官:请你讲讲你对Promise的理解

前言

前段时间的面试中,发现面试官是经常提出对于 Promise 相关的问题。于是本人开始决定来表达自己对于 Promise 的理解。

什么是Promise

首先还是我们的 是什么Promise 是JavaScript中用于处理异步操作的一种解决方案。它可以通过对象的状态来管理异步操作的结果,并提供了一种更加优雅和可靠的方式来处理异步代码。

Promise 中有着三种初始状态,分别是:

  • pending: 这是初始状态,表示异步任务正在处理,状态还没有改变;
  • fulfilled: 这是表示异步操作处理成功的标识;
  • rejected: 这是表示异步操作处理失败的标识。

Promise 中,它接受两个参数 resolvereject 。通过 resolve 我们可以将异步操作成功后的结果返回出去,与此同时状态也会改变为 fulfilled,同理,通过 reject 我们可以将异步操作失败后的结果返回出去,与此同时状态也会改变为 rejected。但是需要注意 :状态一经改变后就不能再次发生改变了,也就是说 resolvereject 只能执行一个。

对于 resolve 出来的值,我们可以在 Promise 对象后加上 .then() 来获取异步操作处理成功所获得的结果,也可以通过 .catch() 来获取异步操作处理失败的结果。

Promise它有哪些方法

对于Promise来说,它身上有着如下的方法:

  • .then(): 这个之前我们也浅略的讲解过一下,这是 Promise 实例最常用的方法之一。它接受两个参数,分别是 onFulfilledonRejected,它们分别是在 Promise 状态变为 fulfilledRejected 时被调用的回调函数。then() 方法返回一个新的 Promise 对象,可以用于链式调用。
  • .catch():这个方法用于捕获 Promise 链中的错误,相当于 then(null, onRejected) 的简写形式。如果 Promise 状态变为 rejected 且没有被捕获,则会调用指定的 onRejected 回调函数。
  • .finallyfinally() 方法用于指定不管 Promise 状态如何都会执行的回调函数 onFinally。无论 Promise 是 fulfilled 还是 rejected,onFinally 回调函数都会被执行。
  • .all():这个方法主要是用于判断是否所有的异步操作都是成功的。该方法接收一个可迭代对象(比如数组)作为参数,返回一个新的 Promise 对象。当传入的所有 Promise 都成功完成时,返回的 Promise 对象才会被成功解析,解析值是一个包含所有 Promise 结果的数组。如果传入的任何一个 Promise 失败,则返回的 Promise 对象会立即被拒绝,拒绝原因是第一个失败的 Promise 的错误信息。
  • .race():该方法也是接收一个可迭代对象作为参数。只要传入的参数中有一个 Promise 状态发生改变,它就会返回这个 Promise 的解析,无论它是成功还是失败的。
  • .any():该方法也是接收一个可迭代对象作为参数。如果参数中有一个对象的状态变更为 fulfilled 他则返回这个对象的值,否则返回一个包含所有错误原因的数组。
  • .allSettle():该方法也是接收一个可迭代对象作为参数。当传入的所有 Promise 都已经成功或失败时,返回的 Promise 对象会被解析,其值是一个包含每个 Promise 结果的对象数组,每个对象包含 statusvaluereason 属性,分别表示该 Promise 的状态和值或原因。

那么你可能就会有一个疑问了,为什么我们在 then 就可以执行异步操作失败后的回调函数,那我为什么还需要catch。 这是因为:

虽然 then() 方法可以捕获异步操作失败后的回调函数,但是在实际开发中,有时候我们可能会有一连串的异步操作,而这些操作中的任何一个失败都会导致整个 Promise 链的失败。在这种情况下,如果每个 then() 都添加失败的回调函数,代码会变得冗长和不易维护。

catch() 方法的作用就是用来捕获整个 Promise 链中的任何错误,并统一处理这些错误。通过在 Promise 链的末尾使用 catch() 方法,我们可以避免在每个 then() 中都添加失败的回调函数,从而使代码更加简洁和易读。

另外,使用 catch() 方法还可以避免忘记在每个 then() 后面添加失败回调函数而导致错误被未捕获。因此,即使 then() 中的失败回调函数已经能够捕获错误,使用 catch() 方法也是一种良好的编程习惯,可以提高代码的健壮性和可维护性。

为什么需要Promise

在 JavaScript 中,异步操作经常涉及到网络请求、文件读写、定时器等等。在过去,我们通常使用回调函数来处理异步操作,但回调函数嵌套会导致代码的可读性变差,产生回调地狱的问题。而 Promise 的出现解决了这个问题,使得异步代码的编写更加清晰和易于维护。

它能干什么

Promise 主要用于处理异步操作,例如:

  • 发起网络请求并获取响应数据。
  • 读取文件或写入文件。
  • 执行定时器任务。
  • 处理事件监听器等。

Promise 可以让异步操作的流程更加清晰和可控,使得代码结构更加优雅,降低了出错的可能性。

Promise 的优缺点

优点:

  1. 更清晰的异步流程: Promise 提供了一种清晰的方式来处理异步操作,通过链式调用的方式使得代码更易读、易维护。
  2. 避免回调地狱: Promise 的链式调用可以避免回调地狱的问题,减少了嵌套层级,使得代码结构更加扁平化。
  3. 更好的错误处理: Promise 提供了 .catch() 方法来统一处理异步操作中的错误,使得错误处理更加方便和一致化。
  4. 更强大的功能: Promise 还提供了一些其他方法,如 Promise.all()Promise.race() 等,用于处理多个异步操作的情况。

缺点:

  1. 无法取消 Promise: 一旦创建了 Promise,就无法取消它,这可能会导致内存泄漏。
  2. 无法得知 Promise 的进度: Promise 只能知道异步操作是成功还是失败,但无法得知其执行的进度,例如完成了多少工作或剩余多少时间。
  3. 只能处理一次结果: Promise 的状态一经改变就不会再变,一旦成功或失败就无法再次改变,这在某些场景下可能不够灵活。

尽管 Promise 存在一些缺点,但它仍然是 JavaScript 异步编程中的重要解决方案,大大提高了异步代码的可读性、可维护性和可靠性。

结语

以上就是本人对于 Promise 的理解了,对于 Promise 我们还是十分有必要去了解并掌握的,它在日常中的使用是十分频繁的。本人也会在下一篇文章中来为大家讲解一下如何去实现一个高级的 Promise 。

相关推荐
阿珊和她的猫23 分钟前
v-scale-scree: 根据屏幕尺寸缩放内容
开发语言·前端·javascript
PAK向日葵2 小时前
【算法导论】PDD 0817笔试题题解
算法·面试
加班是不可能的,除非双倍日工资5 小时前
css预编译器实现星空背景图
前端·css·vue3
wyiyiyi5 小时前
【Web后端】Django、flask及其场景——以构建系统原型为例
前端·数据库·后端·python·django·flask
gnip6 小时前
vite和webpack打包结构控制
前端·javascript
excel6 小时前
在二维 Canvas 中模拟三角形绕 X、Y 轴旋转
前端
阿华的代码王国6 小时前
【Android】RecyclerView复用CheckBox的异常状态
android·xml·java·前端·后端
一条上岸小咸鱼6 小时前
Kotlin 基本数据类型(三):Booleans、Characters
android·前端·kotlin
Jimmy6 小时前
AI 代理是什么,其有助于我们实现更智能编程
前端·后端·ai编程
ZXT7 小时前
promise & async await总结
前端