面试题 -- 对 Promise 的理解?
# 前言
Promise 是异步编程的一种解决方案,它是一个对象,可以获取异步操作的消息,他的出现大大改善了异步编程的困境,避免了地狱回调,它比传统的解决方案回调函数和事件更合理和更强大。
所谓 Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。
# 状态
| 状态 | 解释 |
|---|---|
Pending | 进行中 |
Resolved | 已完成 |
Rejected | 已拒绝 |
当把一件事情交给 promise 时,它的状态就是 Pending,任务完成了状态就变成了 Resolved、没有完成失败了就变成了 Rejected。
注意
一旦从进行状态变成为其他状态就永远不能更改状态了。
# 常用方法
| 状态 | 解释 |
|---|---|
then() | 进then方法可以接收两个回调函数作为参数,第一个回调函数是 promise 对象的状态变为 resolved调用,第二个回调函数是 promise 对象的状态变为 rejected 时调用,其中第二个参数可以省略。行中 |
catch() | 该方法相当于 then 方法的第二个参数,指向 reject 的回调函数。 不过 catch 方法还有一个作用,就是 在执行 resolve 回调函数时,如果出现错误,抛出异常,不会停止运行,而是进入 catch 方法中。 |
all() | 等待机制:Promise 全部子实例都成功才算成功,有一个子实例失败就算失败。状态由数组中所有事件来决定,当有一个事件的状态为 reject,all()方法的状态就是 reject。 |
race() | 赛跑机制:要看最先的 Promise 子实例是成功还是失败。状态由最先结束的事件来决定 |
finally() | 用于指定不管 Promise 对象最后状态如何,都会执行的操作。 |
any() | 等待机制:有一个子实例成功就算成功,全部子实例失败才算失败 |
# 特点
对象的状态不受外界影响。
promise对象代表一个异步操作,有三种状态,pending(进行中)、fulfilled(已成功)、rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态,这也是 promise 这个名字的由来——“承诺”;一旦状态改变就不会再变,任何时候都可以得到这个结果。
promise对象的状态改变,只有两种可能:从pending变为fulfilled,从pending变为rejected。这时就称为resolved(已定型)。如果改变已经发生了,你再对promise对象添加回调函数,也会立即得到这个结果。这与事件(event)完全不同,事件的特点是:如果你错过了它,再去监听是得不到结果的。
# 缺点
- 无法取消
Promise,一旦新建它就会立即执行,无法中途取消。 - 如果不设置回调函数,
Promise内部抛出的错误,不会反应到外部。 - 当处于
pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。
# Promise 解决了什么问题
- 异步编程:可以将异步操作队列化,按照期望的顺序执行,返回符合预期的结果。
- 地狱回调:后一个请求需要依赖于前一个请求成功后,将数据往下传递,会导致多个 ajax 请求嵌套的情况,代码不够直观。
- 信任问题:由于回调存在着依赖反转,在使用第三方提供的方法时,存在信任问题。