JavaScript 실행 컨텍스트, 클로저!
Promise
비동기 특성상 이벤트 처리 콜백 메서드의 순서를 지정할 수 없는데 Promise 객체를 사용하면
문제를 해결할 수 있을 뿐 아니라 콜백 지옥을 해결 가능하다.
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Promise
then, catch, finally 3가지 콜백함수 등록이 가능
finally는 ES2018 에 추가됨
1 | var p = new Promise(function (resolve, reject) { |
p 내부의 비동기 코드 수행 완료 후 resolve-then, reject-catch 세트로 정의된 콜백메서드가 호출된다.
아래처럼 then 메서드에 resolve, reject 메서드를 모두 정의해도 된다.
1 | p.then( |
Promise Chaining - all
위의 then, catch 메서드는 또다른 Promise 객체를 반환하기 때문에 then, catch 를 여러개 묶을 수 있다.
1 | const promiseFirst = new Promise(resolve => resolve(1)) // 그냥 실행 성공 콜백에 1 전달 |
문자열로 인식되어 1이 붙어 111, 211 로 출력된다.
1 | 11 |
then 에 정의된 람다식을 실행 후 resolve 를 호출, 아래의 then 의 정의된 람다식을 호출, 이를 반복하여 chaining 을 구성한다.
Promise.all 전역 메서드를 사용해 여러개의 Promise 객체를 병합하여 새로운 Promise 객체를 생성하는 것도 가능하다.
async, await
async, await 문법을 사용하면 Promise 를 좀 더 편하게 사용할 수 있다.
함수 앞에 비동기 함수임을 뜻하는 async 키워드 사용
값을 반환할 필요는 없지만 반환값이 있을경우 항상 Promise 객체로 감싸서 반환한다.
1 | async function f() { |
await 키워드는 async 메서드 내부에서만 사용가능하며 Promise 를 동기적으로 동작하도록 구성한다.
1 | async function foo() { |
await 는 주로 네트워크 요청이나 파일읽기 같은 시간이 오래걸리는 함수호출문 앞에 사용한다.
1 | const fs = require('fs'); |
try, catch 를 사용해 비동기 메서드 안에서 reject 가 호출되거나 throw 로 예외를 발생시킨 것을 쉽게 처리할 수 있다.
비동기 처리 메서드는 Promise 객체를 반환해야 await가 의도한 대로 동작한다.
그렇다고 async, await 키워드로 비동기 처리를 하려고 꼭 Promise 객체를 정의할 필요는 없다.
아래처럼 async 와 람다식을 사용해 비동기 메서드 정의가 가능하다.
1 | const originPromise = new Promise((resolve, reject) => { |
비동기 처리를 위해 callback을 마지막 매개변수로 넘겨주거나 Promise 객체를 정의하는 것 보다
아래처럼 비동기 메서드를 async, await 키워드로 한번 더 감싸면 코드는 조금 늘어나도 비동기적 사고는 적게할 수 있다.
1 | const newMetaPromise = async () => { |
비동기 반복
반복문 내부에 비동기 구문이 있을 경우
반복문의 완료여부를 기다리고 싶을 때 비동기 반복문을 사용
1 | import axios from "axios"; |
위처럼 비동기반복문을 사용할 경우 빈 배열이 출력된다.
1 | import axios from "axios"; |
for await ...of 구문을 사용하면 반복문 내부의 모든 비동기함수가 완료될 때 까지 다음 구문을 대기한다.