|
|
|
|
@ -0,0 +1,152 @@
|
|
|
|
|
# 异步编程AsyncAwait
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
async function async1() {
|
|
|
|
|
console.log('async1 start');
|
|
|
|
|
await async2();
|
|
|
|
|
console.log('async1 end');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function async2() {
|
|
|
|
|
console.log('async2');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
console.log('script start');
|
|
|
|
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
console.log('setTimeout');
|
|
|
|
|
}, 0);
|
|
|
|
|
|
|
|
|
|
async1();
|
|
|
|
|
|
|
|
|
|
new Promise(function(resolve) {
|
|
|
|
|
console.log('promise1');
|
|
|
|
|
resolve();
|
|
|
|
|
}).then(function() {
|
|
|
|
|
console.log('promise2');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
console.log('script end');
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**实际输出**:
|
|
|
|
|
```
|
|
|
|
|
script start
|
|
|
|
|
async1 start
|
|
|
|
|
async2
|
|
|
|
|
promise1
|
|
|
|
|
script end
|
|
|
|
|
async1 end
|
|
|
|
|
promise2
|
|
|
|
|
setTimeout
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
### 📚 **详细解析**
|
|
|
|
|
|
|
|
|
|
#### **关键点理解**
|
|
|
|
|
`await` 后面的代码相当于被包装在 `Promise.then()` 中,是**微任务**
|
|
|
|
|
|
|
|
|
|
#### **执行步骤分解**:
|
|
|
|
|
|
|
|
|
|
**1. 同步代码执行**:
|
|
|
|
|
```javascript
|
|
|
|
|
console.log('script start'); // 1. script start
|
|
|
|
|
console.log('async1 start'); // 2. async1 start (在async1中)
|
|
|
|
|
console.log('async2'); // 3. async2 (在async2中)
|
|
|
|
|
console.log('promise1'); // 4. promise1 (在Promise构造函数中)
|
|
|
|
|
console.log('script end'); // 5. script end
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**2. 微任务队列状态**:
|
|
|
|
|
- `await async2()` 后的代码被放入微任务队列:`console.log('async1 end')`
|
|
|
|
|
- `Promise.resolve().then(...)` 被放入微任务队列:`console.log('promise2')`
|
|
|
|
|
|
|
|
|
|
**3. 事件循环顺序**:
|
|
|
|
|
```javascript
|
|
|
|
|
// 执行所有微任务(按入队顺序)
|
|
|
|
|
console.log('async1 end'); // 6. async1 end
|
|
|
|
|
console.log('promise2'); // 7. promise2
|
|
|
|
|
|
|
|
|
|
// 执行宏任务
|
|
|
|
|
console.log('setTimeout'); // 8. setTimeout
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 🎯 **重要规则**
|
|
|
|
|
1. **async函数中,`await` 之前的代码是同步执行的**
|
|
|
|
|
2. **`await` 后面的代码会被包装成微任务**
|
|
|
|
|
3. **Promise构造函数中的代码是同步执行的**
|
|
|
|
|
4. **`.then()` 中的回调是微任务**
|
|
|
|
|
|
|
|
|
|
### 💡 **记忆技巧**
|
|
|
|
|
```
|
|
|
|
|
async函数执行流程:
|
|
|
|
|
1. 执行await之前的代码(同步)
|
|
|
|
|
2. 执行await表达式(同步)
|
|
|
|
|
3. 将await后面的代码包装成微任务
|
|
|
|
|
4. 函数暂停,返回Promise
|
|
|
|
|
5. 继续执行函数外部的同步代码
|
|
|
|
|
6. 执行微任务(包括await后面的代码)
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
## **变形题(巩固async/await)**
|
|
|
|
|
```javascript
|
|
|
|
|
async function async1() {
|
|
|
|
|
console.log('async1 start');
|
|
|
|
|
await async2();
|
|
|
|
|
console.log('async1 end');
|
|
|
|
|
await async3();
|
|
|
|
|
console.log('async1 end1');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function async2() {
|
|
|
|
|
console.log('async2');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function async3() {
|
|
|
|
|
console.log('async3');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
console.log('script start');
|
|
|
|
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
console.log('setTimeout');
|
|
|
|
|
}, 0);
|
|
|
|
|
|
|
|
|
|
async1();
|
|
|
|
|
|
|
|
|
|
new Promise(function(resolve) {
|
|
|
|
|
console.log('promise1');
|
|
|
|
|
resolve();
|
|
|
|
|
}).then(function() {
|
|
|
|
|
console.log('promise2');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
console.log('script end');
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## **变形题(巩固async/await)**
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
console.log('1');
|
|
|
|
|
|
|
|
|
|
setTimeout(() => console.log('2'), 0);
|
|
|
|
|
|
|
|
|
|
Promise.resolve().then(() => console.log('3'));
|
|
|
|
|
|
|
|
|
|
async function asyncFunc() {
|
|
|
|
|
console.log('4');
|
|
|
|
|
await Promise.resolve();
|
|
|
|
|
console.log('5');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
asyncFunc();
|
|
|
|
|
|
|
|
|
|
Promise.resolve().then(() => console.log('6'));
|
|
|
|
|
|
|
|
|
|
console.log('7');
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**问题:请写出完整的输出顺序。**
|