在前端工作中,Promise是必不可以,在面试过程中当然也是必考的知识点之一,甚至更有,直接给出一张白纸,请手写一个Promise。

1、两个状态

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
class MyPromise {
constructor(executor) {
// 初始化值
this.initValue()
// 初始化this指向
this.initBind()
// 执行回调传进来的函数
executor(this.resolve, this.reject)
}

initBind() {
this.resolve = this.resolve.bind(this)
this.reject = this.reject.bind(this)
}

initValue() {
// 初始化值
this.PromiseResult = null // promise结果值
this.PromiseState = 'pending' // 等待中
}

resolve(value) {
// 若执行resolve,状态变为fulfilled
this.PromiseState = 'fulfilled'
this.PromiseResult = value
}

reject(reason) {
// 若执行reject,状态变更为rejected
this.PromiseState = 'rejected'
this.PromiseResult = reason
}
}

2、状态不可逆

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
class MyPromise {
constructor(executor) {
// 初始化值
this.initValue()
// 初始化this指向
this.initBind()
// 执行回调传进来的函数
executor(this.resolve, this.reject)
}

initBind() {
this.resolve = this.resolve.bind(this)
this.reject = this.reject.bind(this)
}

initValue() {
// 初始化值
this.PromiseResult = null // promise结果值
this.PromiseState = 'pending' // 等待中
}

resolve(value) {
// 状态不可逆
if(this.PromiseState !== 'pending') return
// 若执行resolve,状态变为fulfilled
this.PromiseState = 'fulfilled'
this.PromiseResult = value
}

reject(reason) {
// 状态不可变逆
if(this.PromiseState !== 'pending') return
// 若执行reject,状态变更为rejected
this.PromiseState = 'rejected'
this.PromiseResult = reason
}
}

3、出现异常,状态rejected

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
class MyPromise {
constructor(executor) {
// 初始化值
this.initValue()
// 初始化this指向
this.initBind()
// 捕获异常 状态变为rejected
try {
// 执行回调传进来的函数
executor(this.resolve, this.reject)
} catch (error) {
this.reject(error)
}
}

initBind() {
this.resolve = this.resolve.bind(this)
this.reject = this.reject.bind(this)
}

initValue() {
// 初始化值
this.PromiseResult = null // promise结果值
this.PromiseState = 'pending' // 等待中
}

resolve(value) {
// 状态不可变更
if(this.PromiseState !== 'pending') return
// 若执行resolve,状态变为fulfilled
this.PromiseState = 'fulfilled'
this.PromiseResult = value
}

reject(reason) {
// 状态不可变更
if(this.PromiseState !== 'pending') return
// 若执行reject,状态变更为rejected
this.PromiseState = 'rejected'
this.PromiseResult = reason
}
}

4、then的两个回调函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// ......
then(onFulFilled, onRejected) {
// 校验then参数函数的类型
onFulFilled = typeof onFulFilled === 'function' ? onFulFilled : val => val
onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason }

if(this.PromiseState === 'fulfilled') {
// 成功状态执行成功回调
onFulFilled(this.PromiseResult)
} else if(this.PromiseState === 'rejected') {
onRejected(this.PromiseResult)
}
}
// ......

5、支持异步和多次调用

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
class MyPromise {
constructor(executor) {
// 初始化值
this.initValue()
// 初始化this指向
this.initBind()
// 捕获异常 状态变为rejected

this.onFulfilledCallback = [];//成功的回调数组
this.onRejectedCallback = []; //失败的回调数组

try {
// 执行回调传进来的函数
executor(this.resolve, this.reject)
} catch (error) {
this.reject(error)
}
}

initBind() {
this.resolve = this.resolve.bind(this)
this.reject = this.reject.bind(this)
}

initValue() {
// 初始化值
this.PromiseResult = null // promise结果值
this.PromiseState = 'pending' // 等待中
}

resolve(value) {
// 状态不可变更
if(this.PromiseState !== 'pending') return
// 若执行resolve,状态变为fulfilled
this.PromiseState = 'fulfilled'
this.PromiseResult = value
this.onFulfilledCallback.forEach(fn => fn(value))
}

reject(reason) {
// 状态不可变更
if(this.PromiseState !== 'pending') return
// 若执行reject,状态变更为rejected
this.PromiseState = 'rejected'
this.PromiseResult = reason
this.onRejectedCallback.forEach(fn => fn(reason))
}

then(onFulFilled, onRejected) {
// 校验then参数函数的类型
onFulFilled = typeof onFulFilled === 'function' ? onFulFilled : val => val
onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason }

if(this.PromiseState === 'fulfilled') {
// 成功状态执行成功回调
onFulFilled(this.PromiseResult)
} else if(this.PromiseState === 'rejected') {
onRejected(this.PromiseResult)
} else if(this.PromiseState === 'pending') {
typeof onFulFilled === 'function' && this.onFulfilledCallback.push(onFulFilled)
typeof onRejected === 'function' && this.onRejectedCallback.push(onRejected)
}

}

}

6、链式回调

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
class MyPromise {
constructor(executor) {
// 初始化值
this.initValue()
// 初始化this指向
this.initBind()
// 捕获异常 状态变为rejected

this.onFulfilledCallback = [];//成功的回调数组
this.onRejectedCallback = []; //失败的回调数组

try {
// 执行回调传进来的函数
executor(this.resolve, this.reject)
} catch (error) {
this.reject(error)
}
}

initBind() {
this.resolve = this.resolve.bind(this)
this.reject = this.reject.bind(this)
}

initValue() {
// 初始化值
this.PromiseResult = null // promise结果值
this.PromiseState = 'pending' // 等待中
}

resolve(value) {
// 状态不可变更
if(this.PromiseState !== 'pending') return
// 若执行resolve,状态变为fulfilled
this.PromiseState = 'fulfilled'
this.PromiseResult = value
this.onFulfilledCallback.forEach(fn => fn(value))
}

reject(reason) {
// 状态不可变更
if(this.PromiseState !== 'pending') return
// 若执行reject,状态变更为rejected
this.PromiseState = 'rejected'
this.PromiseResult = reason
this.onRejectedCallback.forEach(fn => fn(reason))
}

then(onFulFilled, onRejected) {
// 校验then参数函数的类型
onFulFilled = typeof onFulFilled === 'function' ? onFulFilled : val => val
onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason }

// 需要实现链式调用,需要在then函数中返回一个Promise并且做对应的参数判断
const _this = this
const promise2 = new MyPromise((resolve, reject) => {
if(_this.PromiseState === 'fulfilled') {
setTimeout(() => {
try {
const x = onFulFilled(_this.PromiseResult)
_this.resolvePromise(promise2, x, resolve, reject)
} catch (error) {
reject(error)
}
})
} else if(_this.PromiseState === 'rejected') {
setTimeout(() => {
try {
const x = onRejected(_this.PromiseResult)
_this.resolvePromise(promise2, x, resolve, reject)
} catch (error) {
reject(error)
}
})
} else if(_this.PromiseState === 'pending') {
_this.onFulfilledCallback.push(() => {
setTimeout(() => {
try {
const x = onFulFilled(_this.PromiseResult)
_this.resolvePromise(promise2, x, resolve, reject)
} catch (error) {
reject(error)
}
})
})
_this.onRejectedCallback.push(() => {
setTimeout(() => {
try {
const x = onRejected(_this.PromiseResult)
_this.resolvePromise(promise2, x, resolve, reject)
} catch (error) {
reject(error)
}
})
})
}
})

return promise2;

}

/**
*
* @param {新的promise对象} promise2
* @param {上一个then的返回值} x
* @param {promise2的resolve} resolve
* @param {promise2的reject} reject
*/
resolvePromise(promise2, x, resolve, reject) {
if(promise2 === x) {
reject(new TypeError('Chaining cycle.'))
}
if(x && typeof x === 'object' || typeof x === 'function') {
let used;
try {
let then = x.then
if(typeof then === 'function') {
then.call(x, (y) => {
if(used) return;
used = true
this.resolvePromise(promise2, y, resolve, reject)
}, (r) => {
if(used) return;
used = true
reject(r)
})
} else {
if(used) return;
used = true
resolve(x)
}
} catch (error) {
if(used) return;
used = true
reject(e)
}
} else {
resolve(x)
}
}

}

7、其他方法

7.1、all

  1. 接收一个promise数组,若数组中有非promise项,当此项为成功。
  2. promise数组全部执行成功,则返回结果数组;有一项失败,则返回此项失败的结果。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
static all(promises) {
// 结果数组
const result = []
let count = 0
return new MyPromise((resolve, reject) => {
const addData = (index, value) => {
result[index] = value
count++
if (count === promises.length) resolve(result)
}
promises.forEach((promise, index) => {
if (promise instanceof MyPromise) {
promise.then(res => {
addData(index, res)
}, error => reject(error))
}
})
})
}

7.2、race

  1. 接收一个promise数组,若数组中有非promise项,当此项为成功。
  2. 哪个Promise最快得到结果,就返回那个结果,无论成功失败。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
static race(promises) {
return new MyPromise((resolve, reject) => {
promises.forEach(promise => {
if (promise instanceof MyPromise) {
promise.then(res => {
resolve(res)
}, error => {
reject(error)
})
} else {
resolve(promise)
}
})
})
}

7.3、allSettled

  1. 接收一个promise数组,若数组中有非promise项,当此项为成功。
  2. 把每一项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
static allSettled(promises) {
return new Promise((resolve, reject) => {
const result = []
let count = 0
const addData = (status, value, i) => {
result[i] = {
status,
value
}
count++
if (count === promises.length) {
resolve(result)
}
}
promises.forEach((promise, i) => {
if (promise instanceof MyPromise) {
promise.then(res => {
addData('fulfilled', res, i)
}, error => {
addData('rejected', error, i)
})
} else {
addData('fulfilled', promise, i)
}
})
})
}

7.4、any

  1. any和all相反,接收一个promise数组,若数组中有非promise项,当此项为成功。
  2. 若有一项执行成功,则返回成功的结果;若所有的都失败,则抛出Error错误
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
static any(promises) {
return new Promise((resolve, reject) => {
let count = 0
promises.forEach((promise) => {
promise.then(val => {
resolve(val)
}, err => {
count++
if (count === promises.length) {
reject(new AggregateError('All promises were rejected'))
}
})
})
})
}