0. 동기? 비동기?
자바스크립트에서 쓰는 일반적인 함수는 동기적으로 기능한다.
하지만 가끔은 비동기적으로 써야 할 때가 있다.
동기와 비동기는 어떤 차이가 있을까?
동기
- 한번에 한 작업만 수행할 수 있다
- 흐름을 예측하기 쉽다 (호출 순서대로 작동한다)
비동기
- 동시에 여러 작업을 수행할 수 있다
- 흐름을 예측하기 어렵다 (무엇이 먼저 완료될 지 보장이 불가능하다)
✍ 비동기
setTimeout의 동작 또한 비동기로 동작한다고 볼 수 있다.
함수를 호출하고, 설정 시간 동안 기다리는 시간은 다른 흐름에 영향을 주지 않기 때문이다
만약 console.log('사과')
를 하는 함수의 설정 시간을 3초로 잡고,console.log('옥수수')
를 하는 함수의 설정 시간을 1초로 잡은 후
사과를 찍는 함수 호출
옥수수를 찍는 함수 호출
을 하면 console에는 옥수수가 먼저 찍힌다.
이렇게 함수를 호출하고 기다리는 시간 동안 다른 함수의 호출을 방해하지 않는다. = 흐름에 영향을 주지 않는다
📌 Promise
비동기 작업의 단위.
비동기 작업들을 쉽게 관리할 수 있다.
프로미스가 생성된 시점에는 알려지지 않았을 수도 있는 값을 위한 대리자
비동기 연산이 종료된 이후 결과 값과 실패 사유를 처리할 수 있는 처리기를 얻을 수 있다.
promise를 사용하면 비동기 메서드에서 동기 메서드처럼 값을 반환할 수 있다는 장점이 있다.
하지만 최종 결과를 반환하는 것이 아니고
미래의 어떤 시점에 결과를 제공한다는 약속을 반환한다.
Promise의 사용
- 대기(pending) : 이행하지도, 거부하지도 않은 초기 상태
- 이행(fulfilled) : 연산이 성공적으로 완료 => then
- 거부(rejected) : 연산이 실패 => catch
promise가 이행/거부될 때, 프로미스의 then 메서드에 의해 대기열(큐)에 추가된 처리기들이 호출된다.
const myFirstPromise = new Promise((resolve, reject) => {
// 비동기 작업
})
예제를 보면,
new Promise()를 통해 Promise객체를 만든다.
그리고 이 생성자는 함수를 인자로 받는다.new Promise(함수)
생성자가 받는 함수를 executor이라고 부른다
executor
(resolve, reject)=>{}
- 첫 번째 인수로 resolve => executor내에서 호출할 수 있는 또 다른 함수. 성공
- 두 번째 인수로 reject => exeutor내에서 호추할 수 있는 또 다른 함수 실패
특징
- executor 내부에서 에러가 throw되면 그 에러로 reject가 수행된다
- executor의 리턴 값은 무시된다
- 첫 번재 reject / resolve만 유효하다
then, catch
Promise가 끝나고 난 다음 동작을 설정해줄 수 있다 == then, catch
then
- promise가 성공했을 때의 동작
- 인자로 함수를 받는다
catch
- promise가 실패했을 때의 동작
- 인자로 함수를 받는다
종합해서, Promise는
const promise = new Promise((resolve, reject) => {
resolve(); // resolve를 넣으면 '성공'
reject(); // reject를 넣으면 '실패'
});
promise
.then(() => {
console.log("성공");
})
.catch(() => {
console.log("실패");
});
이런 식으로 사용할 수 있다.
📌 async / await
promise를 조금 더 간결하게 사용할 수 있다.
async function 선언은 AsyncFunction 객체를 반환하는 하나의 비동기 함수를 정의.
async 함수에는 await 식이 포함될 수 있다.
이 식은 async 함수의 실행을 일시중지하고, 전달 된 Promise의 해결을 기다린 다음 async 함수의 실행을 다시 완료 후 값을 반환한다.
- async가 붙은 함수는 promise를 반환. promise가 아니면 promise로 감싸 반환
- await을 만나면 promise가 처리될 때까지 기다린다.
async 함수는 항상 promise를 반환한다.
따라서
async function foo() {
return 1
}
이 코드는
function foo() {
return Promise.resolve(1)
}
이와 같다
await 문이 없는 async 함수는 동기적으로 실행된다.
await문이 있어야지 비동기적으로 실행.
자바스크립트는 await를 만나면 프라미스가 처리될 때까지 기다린다.
이 때 await은 then과 catch의 동작을 알아서 처리한다.
=> async 내에서 콜백 함수를 넘기고 흐름을 제어할 필요가 없다
async / await의 사용
function 앞에 async를 붙이고
비동기 부분에 await를 붙이면 된다.
await은 async가 붙은 함수 안에서만 쓸 수 있다.
async function cat(){
let result = await Promise.resolve("meow");
return result;
}
cat() // 'meow'
try - catch를 이용해서 에러를 처리하면 된다.
💛
JavaScript 공식문서 async await
JavaScript 공식문서 promise
[Javascript] 비동기, Promise, async, await 확실하게 이해하기
'✍ 공부 > JavaScript' 카테고리의 다른 글
[ 모던 자바스크립트 Deep Dive ] 변수와 값의 재할당 (0) | 2022.12.25 |
---|---|
[ 모던 자바스크립트 Deep Dive ] 들어가며 (0) | 2022.12.25 |
이벤트 제어하기. 쓰로틀링(throttling)과 디바운싱(debouncing) (0) | 2022.06.12 |
JavaScript 자바스크립트 이벤트 리스너(eventListener) (0) | 2022.06.11 |
Babel이란 무엇일까? (0) | 2022.04.17 |