-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathpromise.js
146 lines (123 loc) · 3.2 KB
/
promise.js
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
/*
* self fulfilled promise implementation
* @Author slashhuang
* 17/3/25
*/
// new Promise((resolve,reject)中resolve,reject对应的symbol
let resolveSymbol = Symbol('resolve');
let rejectSymbol = Symbol('reject');
// Promise的内部状态,需要定义writable false.
const stateSymbol = Symbol('Promise#state');
//promise的状态集合
const fulfillState = 1;
const rejectState = -1;
const pendingState = 0;
//在then/catch中做hook
const resolveFnSymbol = Symbol('Promise#resolveFn');
const rejectFnSymbol = Symbol('Promise#rejectFn');
//Promise内部逻辑,避免暴露给外界开发者看到
const nextThenCatchSymbol = Symbol('nextThenCatch');
const executorMicrotask = Symbol('microtask');
let {defineProperty,RunLater} = require('./util');
//promise shape
class SuperPromise{
constructor(executor){
if(typeof executor!=='function'){
throw new TypeError(`${executor} is not a function`)
};
let resolveFn = val=>this[resolveSymbol](val);
let rejectFn = error=>this[rejectSymbol](error);
defineProperty(this,stateSymbol,pendingState)
try{
executor(resolveFn,resolveFn)
}catch(err){
rejectFn(err)
}
}
RunLater(){
if(!this.microtask){
return
}
let state = this[stateSymbol];
let PromiseVal = this.PromiseVal;
let { newPromise } = this.microtask;
let hookFn= '';
if(state == fulfillState || state == rejectState){
hookFn = state == fulfillState?resolveFnSymbol:rejectFnSymbol;
RunLater(()=>newPromise[hookFn](PromiseVal))
}
}
[resolveSymbol](val){
defineProperty(this,stateSymbol,fulfillState);
this.PromiseVal = val;
this.RunLater()
}
[rejectSymbol](error){
defineProperty(this,stateSymbol,rejectState);
this.PromiseVal = error;
this.RunLater()
}
// fnArr ==> resolve reject
[nextThenCatchSymbol](fnArr,type){
let method = 'resolve';
let resolveFn = fnArr[0];
let rejectFn = fnArr[1];
if(type=='catch'){
method = 'catch';
rejectFn = fnArr[0];
};
//返回新的Promise,pending状态
let newPromise = new SuperPromise((resolve,reject)=>{});
/*
* hook 用来执行本来resolve和reject的逻辑,在我们这里的实现
* 不一定要通过resolve,reject来改变状态
* 但是,对于开发者来说,看不到这一层
*/
newPromise[resolveFnSymbol]=function(val){
let nextValue = resolveFn(val);
if(nextValue instanceof SuperPromise){
nextValue.then(val=>{
this[resolveSymbol](val)
})
}else{
this[resolveSymbol](nextValue)
}
}
newPromise[rejectFnSymbol]=function(val){
let nextValue = rejectFn(val);
if(nextValue instanceof SuperPromise){
nextValue.catch(val=>{
this[rejectSymbol](val)
})
}else{
this[rejectSymbol](nextValue)
}
}
/*
* 推送进microtask队列,构筑链表
* 当microtask对应的caller执行的时候,会遍历microtask找到可以执行的点
* 通知newPromise.hook执行
*/
this.microtask = {
newPromise
};
this.RunLater()
return newPromise
}
then(fn,fn1){
return this[nextThenCatchSymbol]([fn,fn1],'resolve')
}
catch(fn){
return [nextThenCatchSymbol]([fn],'reject')
}
//@TODO
static resolve(){
}
static reject(){
}
static all(){
}
static race(){
}
}
module.exports = SuperPromise;