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

前言

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

什么是Promise

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

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

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

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

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

Promise它有哪些方法

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

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

相关推荐
小poop6 小时前
CSS 基础与实战:从入门到精通网页美化
前端
考研保研资料分享6 小时前
中国人民大学英语笔译保研面经:五校考核、视译口译与择校复盘
面试
Csvn7 小时前
运行时性能
前端
Never_every998 小时前
位图转矢量工具哪个好?实测抠抠图AI位图转矢量工具
大数据·前端
paopaokaka_luck8 小时前
宠物门店经营管理系统(销售与库存联动、进货自动记账、 退换与退款关联、员工个人业绩、ECharts 经营分析、滞销识别与客户分层、宠物档案年龄计算)
前端·javascript·spring boot·mysql·echarts·mybatis·1024程序员节
古希腊掌管代码的神THU9 小时前
为什么DPO中chosen/rejected概率同时下降?
人工智能·深度学习·机器学习·自然语言处理·面试
空中湖9 小时前
用 React 写数据大屏:为什么我不建议用图表库
前端·react.js·前端框架
欣欣之王来了11 小时前
原始HTML插值:v-html指令的使用与安全风险
前端·学习·架构·项目·vue3教程
IT_陈寒11 小时前
Redis的LRU淘汰策略坑了我一整天
前端·人工智能·后端
计算机魔术师11 小时前
砍半价格、参数再涨,国产旗舰追到 Opus 鼻尖了
前端