-
Async / Await 주의해서 다루기Javascript 2020. 4. 25. 15:18
async / await를 다룰 때 주의해야 할 점입니다.
Non Blocking 형태의 I/O 작업을하는 Node.js는 익숙하지 않을 수 있습니다.
let printNum = (number, delaySec) => { setTimeout(() => console.log(number), delaySec); // i/o 작업을 대신한다. }; let logPrintNum = (number, delaySec) => { console.log(`Enter logPrintNum ${number}`); printNum(number, delaySec); console.log(`Exit logPrintNum ${number}`); }; logPrintNum(1, 0); // 결과 Enter logPrintNum 1 Exit logPrintNum 1 undefined 1
위와 같은 경우 코드의 순서와 결과가 일치하지 않는 것입니다..
이러한 콜스택에 비었을 때 큐스택에서 하나씩 꺼내어서 다시 이벤트 루프에서 다시 콜스택에 쌓여서 실행되는 문제점을 해결하기 위해
그리고 콜백함수의 지옥을 해결하기 위해 promise가 나오고 이어서 async / await가 나온 것입니다.
async 키워드는 항상 함수 앞에 붙고, 항상 promise를 리턴합니다.
await는 항상 async 함수 내에서만 사용할 수 있으며, resolve또는 reject를 리턴합니다.
그 흐름에 따라서 위의 코드를 고쳐 보면 다음과 같은 결과가 출력됩니다.
let printNum = async (number, delaySec) => { await setTimeout(() => console.log(number), delaySec); // i/o 작업을 대신한다. }; let logPrintNum = async (number, delaySec) => { console.log(`Enter logPrintNum ${number}`); await printNum(number, delaySec); console.log(`Exit logPrintNum ${number}`); }; logPrintNum(1, 0); // 결과 Enter logPrintNum 1 Exit logPrintNum 1 Promise {<resolved>: undefined} 1
위와 똑같습니다. 달라진게 없습니다.
이유는 setTimeOut이 Promise를 리턴하고 하고 있지 않기 때문입니다.
await은 오직 Promise에 대해서만 유효합니다.
let printNum = (number, delaySec) => { return new Promise((resolve) => setTimeout(() => { console.log(number); resolve(); }, delaySec)); }; let logPrintNum = async (number, delaySec) => { console.log(`Enter logPrintNum ${number}`); await printNum(number, delaySec); console.log(`Exit logPrintNum ${number}`); }; logPrintNum(1, 0); // 결과 Enter logPrintNum 1 Promise {<pending>} 1 Exit logPrintNum 1
이번에는 제대로 나옵니다.
프로미스는 생성자로 콜백함수를 받게 됩니다. 해당 콜백 함수의 첫 번째 인자는 resolve가 됩니다.
resolve가 리턴됨으로 인해서 logPrintNum의 함수내의 await는 resolve가 호출되었음을 알고 그 함수 호출부분으로 다음으로 넘어가게 됩니다.
map에서의 async / await
map 이나 forEach는 순회함수인데 중간에 async를 만났다고 해서 await가 resolve 또는 reject 리턴을 기다리지 않습니다.
map의 파라미터로 async 함수를 넣어 주면 promise 객체 자체가 리턴되게 됩니다.
'Javascript' 카테고리의 다른 글
Vue.js 12가지 모범사례 (0) 2020.05.03 [JS] Javascript 스트링 메서드 (0) 2020.05.02 SVG 모션 Path 그리기 (0) 2020.04.18 JS 이벤트 루프(callback, setTimeout, queue, 싱글스레드) (0) 2020.03.29 JavaScript에서 Priavate 구현 (0) 2020.03.15