什么是Promise?

Promise是JS异步编程中的重要概念,异步抽象处理对象,是目前比较流行Javascript异步编程解决方案之一。
从语法上来说:Promise是一个构造函数。
从功能上来说:promise对象是用来封装一个异步操作并可以获取其结果。

Promises/A+ 规范

为实现者提供一个健全的、可互操作的 JavaScript promise 的开放标准。

相关术语

  • 解决 (fulfill) : 指一个 promise 成功时进行的一系列操作,如状态的改变、回调的执行。虽然规范中用 fulfill 来表示解决,但在后世的 promise 实现多以 resolve 来指代之。
  • 拒绝(reject): 指一个 promise 失败时进行的一系列操作。
  • 拒因 (reason) : 也就是拒绝原因,指在 promise 被拒绝时传递给拒绝回调的值。
  • 终值(eventual value) : 所谓终值,指的是 promise 被解决时传递给解决回调的值,由于 promise 有一次性的特征,因此当这个值被传递时,标志着 promise 等待态的结束,故称之终值,有时也直接简称为值(value)。
  • Promise : promise 是一个拥有 then 方法的对象或函数,其行为符合本规范。
  • thenable : 是一个定义了 then 方法的对象或函数。
  • 异常(exception) : 是使用 throw 语句抛出的一个值。

Promise使用

Promise状态

一个Promise的当前状态必须是以下三种状态中的一种: 等待状态(Pending)、** 执行状态(Fulfilled)** 和 拒绝状态(Rejected)
一旦状态改变就不能再次改变。

语法

1
new Promise( function(resolve, reject) {...} /* executor */  );

Promise接收一个参数executor,executor是带有 resolvereject 两个参数的函数 。Promise构造函数执行时立即调用executor 函数, resolve 和 reject 两个函数作为参数传递给executor(executor 函数在Promise构造函数返回所建promise实例对象前被调用)。resolve 和 reject 函数被调用时,分别将promise的状态改为fulfilled(完成)或rejected(失败)。
相关流程如下图:

1
2
3
4
const promise = new Promise((resolve, reject) => {
// 异步处理
// 处理结束后、调用resolve 或 reject
});

then方法

一个 promise 必须提供一个 then 方法以访问其当前值、终值和据因,只有状态改变为Fulfilled或者Rejected时才会调用then方法,如果状态为Pending则不调用
promise 的 then 方法接受两个参数:

1
promise.then(onFulfilled, onRejected)

onFulfilled 和 onRejected 都是可选参数;如果 onFulfilled 不是函数,其必须被忽略;如果 onRejected 不是函数,其必须被忽略。
then 方法可以被同一个 promise 调用多次,then方法必须返回一个promise对象。

race方法

Promise.race(iterable) 方法返回一个 promise,一旦迭代器中的某个promise解决或拒绝,返回的 promise就会解决或拒绝。

all方法

Promise.all(iterable) 方法返回一个 Promise 实例,此实例在 iterable 参数内所有的 promise 都“完成(resolved)”或参数中不包含 promise 时回调完成(resolve);如果参数中 promise 有一个失败(rejected),此实例回调失败(reject),失败的原因是第一个失败 promise 的结果。

reject方法

Promise.reject()方法返回一个带有拒绝原因的Promise对象。

resolve方法

Promise.resolve(value)方法返回一个以给定值解析后的Promise 对象。如果这个值是一个 promise ,那么将返回这个 promise ;如果这个值是thenable(即带有”then” 方法),返回的promise会“跟随”这个thenable的对象,采用它的最终状态;否则返回的promise将以此值完成。此函数将类promise对象的多层嵌套展平。

手写Promise

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
(function(){
const PENDING = 'pending' //初始状态
const RESOLVED = 'resolved' //成功状态
const REJECTED = 'rejected' //失败状态
//Promise构造函数
function MyPromise(excutor){
const self = this
//初始化状态
self.status = PENDING
self.data = undefined
self.callbacks = [] //每个元素的结构: {onResolved(value){}, onRejected(reason){} }
//resolve方法
function resolve(value){
if(self.status !== PENDING){
return
}
//改变状态,保存数据
self.status = RESOLVED
self.data = value
//如果有待执行回调函数,立即异步执行异步回调函数
if(self.callbacks.length > 0){
setTimeout(()=>{
self.callbacks.forEach(item=>{
item.onResolved(value)
})
})
}
}
//reject方法
function reject(reason){
if(self.status !== PENDING){
return
}
//改变状态,保存数据
self.status = REJECTED
self.data = reason
//如果有待执行回调函数,立即异步执行异步回调函数
if(self.callbacks.length > 0){
setTimeout(()=>{
self.callbacks.forEach(item=>{
item.onRejected(reason)
})
})
}
}
//立即执行excutor函数
try{
excutor(resolve,reject)
}catch(error){
reject(error)
}
}
//Promise对象的then方法
MyPromise.prototype.then = function(onResolved,onRejected){
onResolved = typeof onResolved === 'function' ?onResolved : value => value, //不写默认undefined
//指定默认是失败回调
onRejected = typeof onRejected === 'function' ?
onRejected : reason => {
throw reason
}
const self = this
//返回一个新的promise对象
return new MyPromise((resolve,reject)=>{
function handle(callback){
try{
//回调函数返回的结果
const result = callback(self.data)
if(result instanceof MyPromise){
//返回的数据是Promise
result.then(resolve,reject)//返回新的promise对象
}else{
resolve(result)
}
}catch(error){
reject(error)
}
}
if(self.status === PENDING){
self.callbacks.push({
onResolved(value){
handle(value)
},
onRejected(reason){
handle(reason)
}
})
}else if(self.status === RESOLVED){
setTimeout(()=>{
handle(onResolved)
})
}else{
setTimeout(()=>{
handle(onRejected)
})
}
})
}
//Promise对象的catch方法
MyPromise.prototype.catch = function(onRejected){
return this.then(undefined, onRejected)
}
//Promise的resolve方法
MyPromise.resolve = function(value){
return new MyPromise((resolve,reject)=>{
if(result instanceof MyPromise){
//返回的数据是Promise
result.then(resolve,reject)//返回新的promise对象
}else{
resolve(result)
}
})
}
//Promise的reject方法
MyPromise.reject = function(reason){
return new MyPromise((resolve,reject)=>{
reject(reason)
})
}
//Promise的all方法
MyPromise.all = function(promises){
const values = new Array(promises.length) //保存成功的数据数据
let resolvedCount = 0 //成功的数量
return new MyPromise((resolve,reject)=>{
//遍历执行promises
promises.forEach((item,index)=>{
MyPromise.resolve(item).then(
value=>{
reslovedCount++
values[index] = value
if(reslovedCount === promises.length){
resolve(values)
}
},
reason=>{
reject(reason)
}
)
})
})
}
//Promise的race方法
MyPromise.race = function(promises){
return new MyPromise((resolve,reject)=>{
promises.forEach((item,index)=>{
MyPromise.resolve(item).then(
value=>{
resolve(value)
},
reason=>{
reject(reason)
}
)
})
})
}
window.MyPromise = MyPromise
})()
//使用
var p = new MyPromise((resolve,reject)=>{
resolve(1)
})