【模拟实现】Promise(一)
williamzhou 3/29/2021 面试模拟实现
# 第一版本:同步/异步调用
- 构造函数接受一个 excutor 要立即执行
- executor 接收 promise 提供的两个参数 resolve,reject
- then 接收两个参数,成功回调和失败回调
- 未调用 resolve 或 reject 时,promise 处于pending 状态等待
- resolve 时,执行成功回调
- reject 时,执行失败回调
const STATUS = {
PENDING: 'PENDING',
FULFILLED: 'FULFILLED',
REJECTED: 'REJECTED',
}
class MyPromise {
constructor(executor) {
this.status = STATUS.PENDING
this.value = void(0) // 成功时的返回值
this.reason = void(0) // 失败原因
this.resolvedQueue = [] // 成功回调
this.rejectedQueue = [] // 失败回调
const resolve = value => {
if (this.status === STATUS.PENDING) {
this.status = STATUS.FULFILLED
this.value = value
this.resolvedQueue.forEach(fn => fn())
}
}
const reject = reason => {
if (this.status === STATUS.PENDING) {
this.status = STATUS.REJECTED
this.reason = reason
this.rejectedQueue.forEach(fn => fn())
}
}
try {
executor(resolve, reject)
} catch (error) {
reject(error)
}
}
then (onFullfilled, onRejected) {
// 同步
if (this.status === STATUS.FULFILLED) {
onFullfilled(this.value)
}
if (this.status === STATUS.REJECTED) {
onRejected(this.reason)
}
// 异步 -> 加入回调
if (this.status === STATUS.PENDING) {
this.resolvedQueue.push(() => {
onFullfilled(this.value)
})
this.rejectedQueue.push(() => {
onRejected(this.reason)
})
}
}
}
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
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
# 测试一下
// 同步调用
new MyPromise((resolve, reject) => {
resolve('🙆♂️')
reject('🙅♂️')
}).then(
(value) => {
console.log('[sync fulfilled]', value)
},
(reason) => {
console.log('[sync rejected]', reason)
}
)
// 异步调用
new MyPromise((resolve, reject) => {
setTimeout(() => {
resolve('🙆♂️')
}, 500)
setTimeout(() => {
reject('🙅♂️')
}, 100)
}).then(
(value) => {
console.log('[async fulfilled]', value)
},
(reason) => {
console.log('[async rejected]', reason)
}
)
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
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
# 第二版本:链式调用
先来看看什么是链式调用,先看看以下代码在浏览器的运行结果:
// 同步链式调用
var p1 = new Promise((resolve, reject) => {
resolve('value1')
}).then((value) => {
console.log("log1", value)
return 'value2'
}).then((value) => {
console.log("log2", value);
})
console.log(p1)
// log1 value1
// log2 value2
// 异步链式调用
var p2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('value1')
}, 500)
}).then((value) => {
return new Promise((resolve) => {
console.log("log1", value)
setTimeout(() => {
resolve('value2')
}, 1000)
})
}).then((value) => {
console.log("log2", value);
})
console.log(p2)
// 500毫秒后:log1 value1
// 1500毫秒后:log2 value2
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
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
第二版本,敬请期待!