-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathasync-await.js
105 lines (90 loc) · 2.91 KB
/
async-await.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
// console.log('script start');
async function async1() {
console.log('async1 start');
await async2();
console.log('async1 end');
}
async function async2() {
console.log('async2 start');
}
// async1();
// setTimeout(() => {
// console.log('setTimeout');
// }, 0);
// new Promise((resolve) => {
// console.log('Promise executor');
// resolve();
// }).then(() => {
// console.log('Promise1');
// }).then(() => {
// console.log('Promise2');
// });
// console.log('script end');
// 结果为
/**
* script start
* async1 start
* async2 start
* Promise executor
* script end
* async1 end
* Promise1
* Promise2
* setTimeout
*/
// 一个函数如果加上 async ,那么该函数就会返回一个 Promise,因此 async2 返回的是一个 resolve 状态的 Promise
async function test() {
return '1';
}
console.log(test()); // -> Promise {<resolved>: "1"}
// 经过 babel 转化的代码为
let async1 = (function () {
var _async1 = _asyncToGenerator(function* () {
console.log('async1 start');
yield async2();
console.log('async1 end');
});
return function async1() {
return _async1.apply(this, arguments);
};
})();
let async2 = (function () {
var _async2 = _asyncToGenerator(function* () {
console.log('async2 start');
});
return function async2() {
return _async2.apply(this, arguments);
};
})();
function _asyncToGenerator(fn) {
return function wrapperAsync() {
var gen = fn.apply(this, arguments);
return new Promise(function (resolve, reject) {
function step(key, arg) {
try {
var info = gen[key](arg);
// 执行到 async2 的时候 info === { done: true, value: undefined };
// 执行到 async1 里面的 yield async2 的时候 info === { done: false, value: Promise }, 因为 async2 返回的是一个 resolve 状态的 Promise ,因此 "console.log("async1 end");" 这一行会被滞留到 microTask 的 then 里面的 step('next', value) 执行了。(相当于往微任务队列里插入了一条任务)。如果在这之前有其他先加入 microTask 的任务,那么会先执行其他的任务。
var value = info.value;
} catch (err) {
reject(err);
return;
}
if (info.done) {
resolve(value);
} else {
return Promise.resolve(value).then(
function (val) {
step('next', val); // yield async2 之后的代码在这次 task 里执行
},
function (err) {
step('throw', err);
},
);
}
}
return step('next');
});
};
}
async1();