简易版Promise.md

手写简易版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
// 常量存Promise的状态
const PENDING = 'pending'
const RESOLVED = 'resolved'
const REJECTED = 'rejected'
function MyPromise(fn) {
const that = this
// promise初始状态为pending
that.state = PENDING
// value为resolve时, 传递的参数
that.value = null
// resolve的回调队列
that.resolvedCallbacks = []
// reject回调队列
that.rejectedCallbacks = []

// resole函数实现
function resolve(value) {
// 只有状态为panding才能修改状态
if(that.state === PENDING) {
// 状态改为resolved
that.state = RESOLVED
// 把值传入value
that.value = value
// 执行resolve回调队列
that.resolvedCallbacks.map(cb => cb(that.value))
}
}

function reject(value) {
// 同上
if(that.state === PENDING) {
that.state = REJECTED
that.value = value
that.rejectedCallbacks.map(cb => cb(that.value))
}
}

try{
fn(resolve, reject)
} catch (e) {
reject(e)
}
}

MyPromise.prototype.then = function(onFulfilled, onRejected) {
const that = this
// 判断传入的是否为函数, 如果非函数包装一层往下执行透传
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : v => v
onRejected = typeof onRejected === 'function' ? onRejected : r => {
throw r
}

// 如果状态为panding, 那么把then中的参数(resolve, reject)传入队列
if(that.state === PENDING) {
that.resolvedCallbacks.push(onFulfilled)
that.rejectedCallbacks.push(onRejected)
}

// 如果状态为resolved那么执行onFulfilled函数
if(that.state === RESOLVED) {
onFulfilled(that.value)
}

// 如果状态为reject那么执行onrejeted函数
if(that.state === REJECTED) {
onRejected(that.value)
}
}

new MyPromise((res, rej) => {
setTimeout(() => {
res(1)
}, 0)
}).then(value => {
console.log(value)
})

so, 你觉得一个Promise的结构是怎么样?

  1. 我需要一个对象来保存该promise的状态, 执行的回调队列, 每次promise的结果(promise链)
  2. 我需要rejected/resolved函数, 触发对应状态的回调队列
  3. 我需要then函数解决Promise链问题

使用Class机制重构,重构不了, 如果使用了setTimeout在resolve中取不到this, 走不下去头痛

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
const PENDING = 'pending'
const RESOLVED = 'resolved'
const REJECTED = 'rejected'
class MyPromise {
constructor(fn) {
const that = this
this.state = PENDING
this.value = null
this.resolvedCallbacks = []
this.rejectedCallbacks = []
try{
fn(this.resolve, this.reject)
} catch (e) {
this.reject(e)
}
}
// resole函数实现
resolve(value) {
// 只有状态为panding才能修改状态
if(this.state === PENDING) {
// 状态改为resolved
this.state = RESOLVED
// 把值传入value
this.value = value
// 执行resolve回调队列
this.resolvedCallbacks.map(cb => cb(this.value))
}
}

reject(value) {
// 同上
if(this.state === PENDING) {
this.state = REJECTED
this.value = value
this.rejectedCallbacks.map(cb => cb(this.value))
}
}

then(onFulfilled, onRejected) {
// 判断传入的是否为函数, 如果非函数包装一层往下执行透传
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : v => v
onRejected = typeof onRejected === 'function' ? onRejected : r => {
throw r
}

// 如果状态为panding, 那么把then中的参数(resolve, reject)传入队列
if(this.state === PENDING) {
this.resolvedCallbacks.push(onFulfilled)
this.rejectedCallbacks.push(onRejected)
}

// 如果状态为resolved那么执行onFulfilled函数
if(this.state === RESOLVED) {
onFulfilled(this.value)
}

// 如果状态为reject那么执行onrejeted函数
if(this.state === REJECTED) {
onRejected(this.value)
}
}
}

new MyPromise((res, rej) => {
setTimeout(() => {
res(1)
}, 0)
}).then(value => {
console.log(value)
})