---
title: JavaScript核心篇 - async、await
tags: async, await
description:
---
JavaScript核心篇 - async、await
===
### 什麼是 async 與 await
下面這段程式碼是用**Promise**、**Promise鏈接**,連續性(逐步)發送請求。
```javascript=
function promiseFn(boolean) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (boolean) {
resolve('成功');
} else {
reject('失敗');
};
}, 500);
});
};
promiseFn(true)
.then((res) => {
console.log(res);
return promiseFn(true);
})
.then((res) => {
console.log(res);
})
```
現在要用**async**的方式,逐步發送請求。
要使用`async Function`,在**宣告Function前面要加上async**。
```javascript=
async function getData() {
};
getData();
```
:::success
asyncu意指**非同步**,在**async Function**的作用域內,可以**把Promise轉為同步執行**。
:::
```javascript=
async function getData() {
const res1 = await promiseFn(true);
const res2 = await promiseFn(true);
console.log(res1, res2);
};
getData();
```
:::success
**async Function**就是透過**await**建構子,可以把**非同步執行**的promise**轉為同步執行**。
:::
ex:上面的例子可以簡化成
```javascript=
const getData = async () => {
const res1 = await promiseFn(true);
const res2 = await promiseFn(true);
console.log(res1, res2);
};
getData();
```
ex:用**立即函式**的方式,變成**立即執行不用另外呼叫**的async Function。
```javascript=
(async () => {
const res1 = await promiseFn(true);
const res2 = await promiseFn(true);
console.log(res1, res2);
})();
```
<br>
### 為什麼叫做Async Function
```javascript=
function promiseFn(boolean) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (boolean) {
resolve('成功');
} else {
reject('失敗');
};
}, 500);
});
};
async function getData() {
return await promiseFn(true);
};
console.log(getData());
```
從`console.log(getData())`來看,==**Async Function**本身就是一個Promise==。

所以`getData()`也可以用`.then()`的方式來接收資料。
(`return await promiseFn(true)`是要把==resolve的結果傳出來==)
:::success
在**Async Function**。**return**等同**resolve**,**throw**等同**reject**。
:::
```javascript=
getData()
.then((res) => {
console.log(res);
})
```
#### 如果Async Function接收失敗,怎麼辦?
可以使用**trycatch**,去try(測試)Promise函式能不能動,不行就把catch傳出來(reject()錯誤訊息)。
```javascript=
async function getData() {
try {
return await promiseFn(false);
} catch (error) {
throw(error);
}
};
getData()
.then((res) => {
console.log(res);
})
.catch((err) => {
console.log(err);
});
```
用`throw(error)`把錯誤資訊傳出來。`getData().catch((err) => {})`才能接收到。
<br>
:::success
`await`**無法把非Promise base**的方法轉為**同步執行**。
:::
下面的例子`console.log()`印出的順序1、3、2。
- `setTimeout`不是基於`Promise`,所以`await`==無法==將`setTimeout`轉為同步執行。
```javascript=
(async () => {
console.log('1');
await setTimeout(() => {
console.log('2');
}, 1000);
console.log('3');
})();
```
- 除非用`new Promise`去建立函式,把`setTimeout`包起來。
```javascript=
function delayTime() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(console.log('2'));
}, 1000)
})
};
(async () => {
console.log(1);
await delayTime();
console.log(3);
})();
```
- 這樣就能用`await`把`setTimeout`==轉為同步執行==。
<br>
### async 與 await 的功用與實戰
**範例1**
將原本用**Promise鏈接**撰寫**連續性請求**的方式,改成==用async Function的撰寫方式取代Promise==。
:point_right: [如何撰寫連續性請求Request](https://hackmd.io/ykQHzI04Roi3xntGScVepw#如何撰寫連續性請求Request)
- `axios.get()`前面加上`await`轉為**同步執行**,再賦予給變數res1。
- `console.log(res1.data.results[0])`印出第一筆資料。
- 用解構賦值,取得第一筆資料seed值。
- 因為取得第二筆資料必須跟第一筆**相同**,所以取第二筆資料的==API要加上seed值==, `https://randomuser.me/api/?seed=${seed}`才能**取得同一筆資料**。
- 要加上`trycatch`才能把**錯誤訊息**傳出來。
```javascript=
(async () => {
try {
const res1 = await axios.get('https://randomuser.me/api/');
console.log(res1.data.results[0]);
const { seed } = res1.data.info;
const res2 = await axios.get(`https://randomuser.me/api/?seed=${seed}`);
console.log(res2.data.results[0]);
} catch (error) {
throw(error);
}
})();
```
<br>
**範例2**
將原本用**Promise**撰寫**同時請求**的方式,改成==用async Function的撰寫方式取代Promise==。
:point_right: [如何撰寫同時發出多個請求](https://hackmd.io/ykQHzI04Roi3xntGScVepw#如何撰寫同時發出多個請求)
- 要加上`trycatch`才能把**錯誤訊息**傳出來。
```javascript=
async function getData () {
try {
return await Promise.allSettled([
axios.get('https://randomuser.me/api/'),
axios.get('https://randomuser.me/api/'),
axios.get('https://randomuser.me/api/'),
]);
} catch (error) {
throw(error);
}
};
getData()
.then((res) => {
console.log(res);
})
.catch((err) => {
console.log(err);
});
```