手写一个简单的promise

手写一个简单的promise

promise是什么?

promise是js异步编程的解决方案,比传统的回调函数的方式更合理和强大,完美解决回调地狱,使的异步操作更加容易

Promises/A+规范

想要编写一个完整的,规范的promise就要哦根据promises/A+规范编写

https://promisesaplus.com/英文地址

https://blog.csdn.net/qq_41800366/article/details/120788569?spm=1001.2014.3001.5501中文地址

最简单的promise使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
let  p = new Promise((resolve,reject)=>{
settimeOut(()=>{
if(true){
resolve('true')
}else{
reject('false')
}
},1000)
})

p.then(value => {
console.log(value) // true
}).catch(err => {
console.log(err) // false
})

写一个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
promise是一个构造函数
new Promise传入一个函数立即执行
执行函数有resolve和reject两个参数
有一个then方法,接收两个参数
class Promise {
contructor(exector){
const resolve = value => {
console.log(value)
}

const reject = reason => {
console.log(reason)
}

try{
exector(resolve,reject)
} catch(err) {
throw err
}
}
then(arg1,arg2){

}
}

let p = new Promise((resolve,reject)=>{

})

promise的状态

pending,fullfilled:解决/resolved,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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
三个状态
调用resolve和reject时状态要从pending变为fullfilled或者rejected
const PENDING = 'pending'
const FULLFILLED = 'fullfilled'
const REJECT = 'rejected'
class Promise {
contructor(exector){
this.state = PENDING //初始pending状态
this.value = undefined
this.reason = undefined
this.obFullFillCallBack = undefined //保存promise内部执行的函数
this.onRejectedCallBack = undefined //保存执行的函数
const resolve = value => {
if(this.state = PENDING){
this.state = FULLFILLED
this.value = value
this.onFUllFillCallBack && this.onFUllFillCallBack()
}
}

const reject = reason => {
if(this.state = PENDING){
this.state = REJECT
this.reason = reason
this.onRejectedCallBack() && this.onRejectedCallBack()
}
}

try{
exector(resolve,reject)
} catch(err) {
throw err
}
}
then(onFullfilled,onRejected //都是可选参数,如果不是函数直接忽略){
// typeof onFullfilled === 'function' && onFullfilled()
// typeof onRejected === 'function' && onRejected()
if(this.state === FULLFILLED){
typeof onFullfilled === 'function' && setTimeout(()=>{
onFullfilled(this.value)
},0)
}else if(this.state === REJECTED){
typeof onRejected === 'function' && setTimeout(()=>{
onRejected(this.reason)
},0)
} else {
typeof onFullfilled === 'function' && (this.onFUllFillCallBack = value => {
setTimeout(()=>{
onFullfilled(value)
},0)
})
type onRejected === 'function' && (this.onRejectedCallBack = reason => {
setTimeout(()=>{
onRejected(reason)
},0)
}
}
}
}

let p = new Promise((resolve,reject)=>{

})

再修改一下 //最基础版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
const PENDING = 'pending'
const FULLFILLED = 'fullfilled'
const REJECT = 'rejected'
class Promise {
contructor(exector){
this.state = PENDING //初始pending状态
this.value = undefined
this.reason = undefined
this.obFullFillCallBacks = [] //保存promise内部执行的函数
this.onRejectedCallBacks = [] //保存执行的函数
const resolve = value => {
if(this.state = PENDING){
this.state = FULLFILLED
this.value = value
this.onFUllFillCallBacks && this.onFUllFillCallBacks.forEach(fn => fn(value))
}
}

const reject = reason => {
if(this.state = PENDING){
this.state = REJECT
this.reason = reason
this.onRejectedCallBacks && this.onRejectedCallBacks.forEach(fn => fn(reason))
}
}

try{
exector(resolve,reject)
} catch(err) {
throw err
}
}
then(onFullfilled,onRejected //都是可选参数,如果不是函数直接忽略){
// typeof onFullfilled === 'function' && onFullfilled()
// typeof onRejected === 'function' && onRejected()
if(this.state === FULLFILLED){
typeof onFullfilled === 'function' && setTimeout(()=>{
onFullfilled(this.value)
},0)
}else if(this.state === REJECTED){
typeof onRejected === 'function' && setTimeout(()=>{
onRejected(this.reason)
},0)
} else {
typeof onFullfilled === 'function' && (this.onFUllFillCallBack.push(value => {
setTimeout(()=>{
onFullfilled(value)
},0)
}))
type onRejected === 'function' && (this.onRejectedCallBack.push(reason => {
setTimeout(()=>{
onRejected(reason)
},0)
})
}
}
}

let p = new Promise((resolve,reject)=>{

})

完整版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
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
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';

function resolvePromise(promise, x, resolve, reject) {
if (promise === x) {
reject(new TypeError('Chaining cycle detected for promise'));
} else if (typeof x === 'function' || (typeof x === 'object' && x !== null)) {
let called = false;
try {
const then = x.then;
if (typeof then === 'function') {
then.call(x, y => {
if (called) return;
called = true;
resolvePromise(promise, y, resolve, reject);
}, r => {
if (called) return;
called = true;
reject(r);
});
} else {
resolve(x);
};
} catch (error) {
if (called) return;
called = true;
reject(error);
}
} else {
resolve(x);
}
};

class FullPromisePerfect {
state = PENDING;
value = undefined;
reason = undefined;
onFulfilledCallback = [];
onRejectedCallback = [];

constructor(executor) {
const resolve = value => {
if (this.state === PENDING) {
this.state = FULFILLED;
this.value = value;
this.onFulfilledCallback.forEach(onFulfilled => onFulfilled(value));
}
};

const reject = reason => {
if (this.state === PENDING) {
this.state = REJECTED;
this.reason = reason;
this.onRejectedCallback.forEach(onRejected => onRejected(reason));
}
};

try {
executor(resolve, reject);
} catch (error) {
reject(error);
};
};

then(onFulfilled, onRejected) {
const onFulfilledNow = typeof onFulfilled === 'function' ? onFulfilled : value => value;
const onRejectedNow = typeof onRejected === 'function' ? onRejected : reason => { throw reason };
const promise2 = new FullPromisePerfect((resolve, reject) => {
const handleResolve = value => {
try {
const x = onFulfilledNow(value);
resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
};
};

const handleReject = reason => {
try {
const x = onRejectedNow(reason);
resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
};
};

if (this.state === FULFILLED) {
setTimeout(() => handleResolve(this.value), 0);
} else if (this.state === REJECTED) {
setTimeout(() => handleReject(this.reason), 0);
} else {
this.onFulfilledCallback.push(value => setTimeout(() => handleResolve(value), 0));
this.onRejectedCallback.push(reason => setTimeout(() => handleReject(reason), 0));
}
});

return promise2;
};
};

module.exports = FullPromisePerfect;

测试

想要测试写的代码,可以使用npm i promises-aplus-tests -D

随后编写测试文件

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
yarn add promises-aplus-tests -D
在 package.json 中添加脚本

"scripts": {
"test": "promises-aplus-tests 填写测试文件地址" // 如 ./src/testFullPromise.js
},

首先在 FullPromise.js 中导出 FullPromise

module.exports = FullPromise;
然后编写测试文件

const FullPromise = require('../FullPromise'); // 导入 FullPromise
// 参照 promises-tests 仓库提供的方法
FullPromise.defer = FullPromise.deferred = function(){
let dfd = {};
dfd.promise = new FullPromise((resolve, reject)=>{
dfd.resolve = resolve;
dfd.reject = reject;
});
return dfd;
};

module.exports = FullPromise; // 最后导出即可
运行命令即可开始测试

yarn test

ending