# Async, Await in axios
問題起源: 在for迴圈中執行非同步api,會因為時間差導致for loop還沒跑完,for loop之後的提前執行,造成無法使用非同步return 回來的值做後續判斷。
### 關於Async
>async function 會回傳 Promise 的函式
基本寫法:
```javascript=
// basic function
async function aaa () {}
//arrow function
const aaa = async () => {}
```
### Await
> 必須包在 async 裡面,並放在 Promise 之前, **每一個 async function 都會回傳一個 promise**
```javascript=
async function aaa () {
await bbb()
}
function bbb () {
console.log("hello")
}
```
執行實例(讓我豁然開朗的code)
```javascript=
main(); // STEP 1-1
function main() {
console.log('start run'); // STEP 1-2
get((value) => {
// STEP 1-3
console.log('value in get', value); // STEP 2-1
process(value, function (result) {
// STEP 2-2
console.log(result); // STEP 3-2
});
});
}
function get(callback) {
console.log('run fn get'); // STEP 1-4
return setTimeout(function () {
// STEP 1-5 into STEP 2
callback('get data'); // STEP 2 會在兩秒後執行
}, 2000);
}
function process(value, callback) {
console.log('value in process', value); // STEP 2-3
return setTimeout(function () {
// STEP 2-4 in to STEP 3
callback(`${value}-secrete`); // STEP 3-1 會在等 1 秒(共 3 秒)後執行
}, 1000);
}
```
:exclamation::exclamation: 在迴圈中使用注意事項
在 for, while 或 for...of 這種迴圈中可以正常使用,如果是有 callback 的迴圈中,例如 forEach, map, filter, reduce ,需要特別注意。
舉例使用filter:
1. Use **map** to return an array promises
2. **await** the array of promises
3. **filter** the resolved values
```javascript=
const fruitBasket = {
apple: 27,
grape: 0,
pear: 14
}
const fruitsToGet = ['apple', 'grape', 'pear'];
const getNumFruit = fruit => {
return fruitBasket[fruit]
}
//重頭戲
const filterLoop = async () => {
console.log('Start')
const promises = await fruitsToGet.map(fruit => getNumFruit(fruit))
const numFruits = await Promise.all(promises)
const moreThan20 = fruitsToGet.filter((fruit, index) => {
const numFruit = numFruits[index]
return numFruit > 20
})
console.log(moreThan20)
console.log('End')
}
//執行順序:
//'Start'
// ['apple']
// 'End'
```
如果直接用filter 加async await,會回傳沒有篩選的陣列。
### How to use Promise in axios
```javascript=
aaa() {
// 初始化一個新的Promise物件
return new Promise((resolve, reject) => {
axios.get(url)
.then(function () {
resolve();
})
.catch(function (error) {
resolve();
});
});
}
```
在new Promise() 的括號裡面要寫一個 callback function,附上兩個參數
- resolve() 表成功,將回傳值塞在()內
- reject() 表失敗,將回傳值塞在()內
### 總結
```javascript=
async aaa() {
const alert = false;
for(let i=0; i<0.length; i++) {
alert = await bbb(i);
if (await alert) {
alert("成功");
} else {
alert("失敗");
}
}
},
bbb() {
return new Promise((resolve, reject) => {
axios.post(url)
.then(function () {
resolve();
})
.catch(function (error) {
resolve();
});
});
}
```
參考來源:
https://zellwk.com/blog/async-await-in-loops/
https://pjchender.dev/javascript/js-async-await/#%E5%9C%A8%E8%BF%B4%E5%9C%88%E4%B8%AD%E4%BD%BF%E7%94%A8-asyncawait