ES6自己实现简易promise

ES5 实现

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
// function Promise(???){
// ???
// return ???
// }

var __PENDING = 'pending'
var __RESOLVED = 'resolved'
var __REJECTED = 'rejected'

function Promise(fn) {
var status = __PENDING
var resolvedArr = []
var rejectedArr = []

function resolveFn() {
status = __RESOLVED
todoThen.apply(undefined, arguments)
}

function rejectFn() {
status = __REJECTED
todoThen.apply(undefined,arguments)
}

fn.call(undefined, resolveFn, rejectFn)

function todoThen() {
setTimeout(() => {
if (status === __RESOLVED) {
for (let i = 0; i < resolvedArr.length; i++) {
resolvedArr[i].apply(undefined, arguments)
console.log(arguments[0])
}
}
if (status === __REJECTED) {
for (let i = 0; i < rejectedArr.length; i++) {
rejectedArr[i].apply(undefined, arguments)
}
}
})
}

return {
then: function(successfn, errfn) {
resolvedArr.push(successfn)
rejectedArr.push(errfn)
return undefined
}
}
}

var promise = new Promise(function(x,y){
setTimeout(()=>{
x(101)
}, 1000)
})
promise.then((z)=>{
console.log(z) // 101
})

ES6 实现(未完待续)

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
const statusProvider = (promise, status) => data => {
if (promise.status !== 'pending') {
return false
}
switch (status) {
case FULFILLED: return Promise.successListener.forEach(fn => fn(data))
case REJECTED: return Promise.failListener.forEach(fn => fn(data))
}
promise.status = status
promise.result = data
}

class Promise {
constructor(executor) {
this.status = 'pending'
this.result = undefined
this.successListener = []
this.failListener = []
executor(data => statusProvider(this, 'resolved'), err => statusProvider(this, 'reject'))
}
then(...args) {
switch (this.status) {
case 'pending': {
this.successListener.push(args[0])
this.failListener.push(args[1])
break
}
case 'resolved': {
args[0](this.result) // 是要处理这种情况,但是不应该在这里调用
break
}
case 'reject': {
args[1](this.result)
}
}
}
catch(arg) {
return this.then(undefined, arg)
}
}