一. promise简单实现
1 | class MyPromise { |
二. 测试代码
测试基本功能———测试代码1
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
48const MyPromise = require('./my-promise.js');
const ThePromise = MyPromise;
const fs = require('fs');
const test = () => {
const pro = new ThePromise((resolve, reject) => {
fs.readFile('./a.js', 'utf-8', (err, data) => {
if (err) {
throw err;
}
console.log('data111:', data);
resolve(data);
});
});
console.log('pro', pro);
const pro2 = pro.then(
value => {
console.log('data2222:', value);
return new ThePromise(resolve => {
fs.readFile('./a.js', 'utf-8', (err, data) => {
if (err) {
throw err;
}
console.log('data3333:', data);
resolve(data);
});
});
},
reason => {
throw reason;
}
);
// 注意这里是pro2.then 如果是pro.then 那么执行顺序会不一样
pro2.then(data => {
console.log('data4444:', data);
return new ThePromise(resolve => {
fs.readFile('./a.js', 'utf-8', (err, data) => {
if (err) {
throw err;
}
console.log('data555:', data);
resolve(data);
});
});
});
};
test();测试promise.all功能——–测试代码2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24const MyPromise = require('./my-promise.js');
const ThePromise = MyPromise;
const fs = require('fs');
const testAll = function() {
const pro1 = new MyPromise((resolve, reject) => {
fs.readFile('./a.js', 'utf-8', (err, data) => {
console.log('a.js:', data);
resolve(data);
});
});
const pro2 = new MyPromise((resolve, reject) => {
fs.readFile('./b.js', 'utf-8', (err, data) => {
console.log('b.js:', data);
resolve(data);
});
});
MyPromise.all([pro1, pro2]).then(arr => {
console.log('arr[0]:', arr[0]);
console.log('arr[1]:', arr[1]);
});
};
testAll();测试promise.race功能———测试代码3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22const MyPromise = require('./my-promise.js');
const ThePromise = MyPromise;
const fs = require('fs');
const testRace = function() {
const pro1 = new MyPromise((resolve, reject) => {
fs.readFile('./a.js', 'utf-8', (err, data) => {
console.log('a.js:', data);
resolve(data);
});
});
const pro2 = new MyPromise((resolve, reject) => {
fs.readFile('./b.js', 'utf-8', (err, data) => {
console.log('b.js:', data);
resolve(data);
});
});
MyPromise.race([pro1, pro2]).then(data => {
console.log('race-result:', data);
});
};
testRace();
三. 注意点
一个promise在resolve之后,就会按照顺序执行这个promise所有的then函数里所注册的函数。
注意是这个promise。而不是由then函数重新生成的promise。
比如
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18const pro1 = new Promise((resolve, reject) => {resolve('aaa')})
const pro2 = pro1.then((data) => {
// 这是一个异步操作
// 打印点0
fs.readFile('./b.js', 'utf-8', (err, data) => {
// 打印点1
console.log('b.js:', data);
resolve(data);
});
}, (reason) => {console.log(reason)});
const pro22 = pro1.then(data => {
// 打印点2
consolele.log(data);
}, (reason) => {console.log(reason)});
const pro3 = pro2.then((data) => {
// 打印点3
console.log(data);
});打印顺序为:打印点0 打印点2 打印点1 打印点3
原因:0,1 和2本来都是应该在pro1被resolve之后就会执行,但是打印完0之后,1是在一个异步函数结束之后才会打印,所以pro1.then会先返回一个pending状态的promise,并且继续执行pro1的第二个then函数。而打印点3是必须要pro1的第一个then函数所返回的promise被resolve只有才能执行的,所以会在最后打印。
由此可见,promise之所以能够保持异步函数执行顺序,是因为每个promise只有一个then函数,在then函数里面又重新返回一个promise,然后下一个promise是在前一个then函数所返回的promise被resolve之后才执行,也就是这样:
1
2
3
4
5// 可以保证顺序:
pro1.then().then().then()
// 下面两个then之间在有异步操作情况下不可以保证顺序,但是pro1和他对应的then还是可以保证顺序的
pro1.then()
pro1.then()也就是说:
一个promise如果对应了两个then,而这两个then中又有异步操作的话,这两个then是无法保证顺序的。
只有promise的入参函数里面的操作和这个promise的then函数里面的操作才是保证执行先后顺序的:即promise的入参函数里面的操作先执行,then函数里面的操作后执行。
而两个并列的then函数之间如果有异步操作则无法保证顺序,同步的话还是可以保证按照顺序执行的。因为从上面实现代码可以看出来,当promise的入参函数返回的promise是pending状态时,then函数里面的操作是被存入一个数组里,等待promise被resolve再拿出来执行;当promise的入参函数返回的promise是resolve或者reject状态时,则直接可以执行相应的then函数里面的操作,不需要存入数组了