# 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