promise
一个 Promise 必然处于以下几种状态之一:
- 等待(pending) : 初始状态,既没有被兑现,也没有被拒绝。
- 成功(fulfilled) : 意味着操作成功完成。
- 失败(rejected) : 意味着操作失败。
我们来看看原生promise
1 | var p0 = new Promise((resolve,reject) => { |
通过输出结果我们可以总结出
- 当没有执行
resolve或者reject时,PromiseState是pending状态 - 当执行
resolve或者reject时,PromiseState会变成相应的成功或失败状态 - 状态只能由
Pending --> fulfilled或者Pending --> rejected,且一但发生改变便不可二次修改
根据上面的总结,我们来一一实现
1 | class MyPromise { |
可以发现已经实现了简单的功能
then
看看原生的promise的then
1 | var p1 = new Promise((resolve,reject) => { resolve('成功') }) |
- then接收两个回调函数,一个是
成功回调,一个是失败回调 - 当
resolve或reject遇到定时器时,等待定时器结束后才执行then
遇到定时器等异步操作的时候的思路
- 当执行
then的时候状态是pending就代表遇到了异步操作,需要保存then里的回调在数组里 - 当定时器结束的时候再执行存储回调数组用数组保存回调的原因: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
46class MyPromise {
constructor(executor) {
// 初始化值
this.PromiseState = 'pending'
this.PromiseResult = null
// 异步存储回调 -----新增代码
this.onFulfilledCallBack = []
this.onRejectedCallBack = []
// 绑定this
this.resolve = this.resolve.bind(this)
this.reject = this.reject.bind(this)
// 执行传进来的函数
executor(this.resolve,this.reject)
}
resolve(value){
if(this.PromiseState === 'pending') {
this.PromiseState = 'fulfilled'
this.PromiseResult = value
// -----新增代码
while(this.onFulfilledCallBack.length) {
this.onFulfilledCallBack.shift()(value)
}
}
}
reject(reason){
if(this.PromiseState === 'pending') {
this.PromiseState = 'rejected'
this.PromiseResult = reason
// -----新增代码
while(this.onRejectedCallBack.length) {
this.onRejectedCallBack.shift()(reason)
}
}
}
then(onFulfilled,onRejected){
if (this.PromiseState === 'fulfilled'){
onFulfilled(this.PromiseResult)
} else if(this.PromiseState === 'rejected'){
onRejected(this.PromiseResult)
} else if (this.PromiseState === 'pending') { // -----新增代码
this.onFulfilledCallBack.push(onFulfilled)
this.onRejectedCallBack.push(onRejected)
}
}
}then方法是可以被多次调用的,如下3s后输出1
2
3
4
5
6
7
8
9
10
11var p1 = new Promise((resolve,reject) => {
setTimeout(() => {
resolve('成功')
},3000)
})
p1.then(value => {
console.log(value + 1)
})
p1.then(value => {
console.log(value + 2)
})成功1,成功2
then的链式调用
怎么让promise可以一直链式的调用then呢?
只需要在then执行返回一个Promise对象就行了
1 | then(onFulfilled,onRejected){ |
为了加深代码的理解,我们分三种情况理解
1. 当then里执行的不是return的时候,例如
1 | p1.then(res => { |
当上述代码执行到const x = onFulfilled(this.PromiseResult)这一句的时候相当于立即执行回调,等效于=>const x = ((res) => {console.log(res)})('成功')
2. 当then里return的是普通变量的时候,例如
1 | p1.then(res => { |
返回一个promise,当再调用then的时候就把x的值传递过去实现了链式调用
3. 当then里return的是promise对象的时候,例如
1 | var p1 = new MyPromise((resolve,reject) => { |
- 当返回值是promise对象时,成功则新promise的对象(即
promise2)返回的是成功,反之则失败
之所以在resolvePromise方法中,遇到promise对象调用 then 方法,是因为只有then才能知道promise返回的状态是成功还是失败。
4. 当then里return的是promise对象自己的时候,会报错。例如
1 | const promise = new Promise((resolve, reject) => { |
所以我们需要对这种情况进行处理










