什么是promise
promise
翻译是 承诺,许诺 的意思,promise
是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。它由社区最早提出和实现,ES6将其写进了语言标准,统一了用法,原生提供了promise
对象。
所谓promise
,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,promise
是一个对象,从它可以获取异步操作的消息。promise
提供统一的 API,各种异步操作都可以用同样的方法进行处理
- 没有异步就不需要
promise
。 promise
本身不是异步,只是我们去编写异步代码的一种方式
我们知道JavaScript中所有代码都是单线程执行的,所以导致JavaScript的所有网络操作,浏览器事件,都必须是异步执行。
异步执行可以用回调函数实现,功能没有任何问题,但是这个写法比较讨厌— 这就是臭名昭著的回调地狱(callback hell)。
针对这个写法,非常的糟糕,需要有一种机制,让这个写法变得更加优雅一些。
所以,在前端社区中,就有一些牛人,纷纷提供了一些新的写法,以避免回调地狱。
后来,es6就在这些基础之上,将promise
直接纳入的规范。从而成为es6中的标准用法
promise A+规范
由于promise
本身出自于民间,就有很多不同的实现版本。
Es6将promise
纳入自己规范的时候,也遵循了一个相应的标准 – promise
A+规范。
将其归纳为4321规范。
- 4:4大术语
- 3:3种状态
- 2:2种事件
- 1:1个对象
4大术语
一定要结合异步操作来理解。
既然是异步,这个操作需要有个等待的过程,从操作开始,到获取结果,有一个过程的。
解决(fulfill):指一个 promise
成功时进行的一系列操作,如状态的改变、回调的执行。虽然规范中用 fulfill 来表示解决,但在后世的 promise
实现多以 resolve 来指代之。
拒绝(reject):指一个 promise
失败时进行的一系列操作。
终值(eventual value):所谓终值,指的是 promise
被解决时传递给解决回调的值,由于 promise
有一次性的特征,因此当这个值被传递时,标志着 promise
等待态的结束,故称之终值,有时也直接简称为值(value)。
据因(reason):也就是拒绝原因,指在 promise
被拒绝时传递给拒绝回调的值。
3种状态
当操作完成时,就有相应的结果,结果有两种:
- 成功了
- 失败了
一共是3种状态,如下:
- 等待态(Pending)
- 执行态(Fulfilled)
- 拒绝态(Rejected)
针对每一种状态,有一些规范:
等待态(
Pending
)
处于等待态时,promise
需满足以下条件:
- 可以迁移至执行态或拒绝态
执行态(
Fulfilled
)
处于执行态时,promise
需满足以下条件:
- 不能迁移至其他任何状态
- 必须拥有一个不可变的终值
拒绝态(
Rejected
)
处于拒绝态时,promise
需满足以下条件:
- 不能迁移至其他任何状态
- 必须拥有一个不可变的据因
2种事件
针对3种状态,只有如下两种转换方向:
- pending --> fulfilled
- pendeing --> rejected
在状态转换的时候,就会触发事件。
- 如果是pending --> fulfiied,就会触发onFulFilled事件
- 如果是pendeing --> rejected,就会触发onRejected事件
1个对象
就是指promise
对象
promise使用
在es6中,提供了promise
构造器,这个promise
构造器,必须要传递一个参数。
构造器的参数,是一个回调函数,包含两个参数: resolve
, reject
promise实例化
实例化
let a = new promise((resolve, reject) => {
// resolve("ok")
reject("NOK")
})
当前这个对象处于 pending
状态。
回调函数中的两个参数,其作用就是用于转换状态:
resolve
,将状态从pending --> fullFilled
reject
,将状态从pending --> rejected
直接使用函数调用的方式来进行转换,在转换的时候必须要传递相应参数
- Resolve函数的参数,就是指 终值(value)
- Reject函数的参数,就是指 据因(reason)
then方法
let a = new Promise((resolve, reject) => {
resolve("ok") // 终值
reject("NOK") //据因
})
怎么获取这里的终值和据因呢?
引入事件机制,三种状态,只有两种转换方向
在状态转换的时候,就会触发事件。
如果是pending --> fulfiied,就会触发onFulFilled事件
如果是pendeing --> rejected,就会触发onRejected事件
在调用resolve方法或者reject方法的时候,就一定会触发事件。
需要注册onFulFilled事件 和 onRejected事件
针对事件的注册,Promise对象提供了then方法,如下:
promise.then(onFulFilled,onRejected)
a.then(function (res) {
console.