Codestates SEB FE 42기/정리노트

S2 unit3 | (동기, 비동기) callback, Promise, async&await

2realzoo 2022. 11. 25. 22:44

📌 동기 (Synchronous)

: 일을 처리할 때, 하나의 일이 끝나고 다음 일을 받아서 처리하는 방식.

=> 일이 끝날 때까지 기다려야 한다

📌 비동기 (Asynchronous)

: 우선 모든 일을 받고, 동시에 처리한다.

동기, 비동기의 시간적 차이

요청을 해두고 일을 진행하다가 response가 오면 받는다.

Asynchronous의 단점은 순서를 예상하기 어렵다는 점이 있다.

 

비동기의 주요 사례

  • DOM Element의 이벤트 핸들러
    • 마우스, 키보드 입력 (click, keydown 등)
    • 페이지 로딩 (DOMContentLoaded 등)
  • 타이머
    • 타이머 API (setTimeout 등)
    • 애니메이션 API (requestAnimationFrame)
  • 서버에 자원 요청 및 응답
    • fetch API
    • AJAX (XHR)

비동기 예제

console창에 A B C가 랜덤으로 찍힌다.

 

setTimeout(function[,delay]) 🔗

: delay 밀리초 단위의 시간 이후에 function 실행

Math.random()으로 A, B, C 각각의 console.log() 시간을 달리해서 비동기로 실행된다.

 

 

📌 순서 제어 방법

✅ Callback

: 어떤 함수에서 전달인자로 받는 함수

✔ 이벤트에서의 잘못된 사용법

document.queryselector('.btn').onclick = callbackFunc()

함수의 실행값을 이벤트에 주었기 때문에 클릭해도 함수가 실행되지 않는다.

함수에 처음 들어올 당시 콜백함수를 실행하고 종료되었기 때문이다.

handle함수 자체를 할당했을 땐 버튼을 누를 때마다 console.log('button clicked!')가 실행되었다.

handle()을 재할당 한 후에는 할당 당시에만 실행되고, 이후엔 버튼을 눌러도 함수가 실행되지 않았다.

 

✔ 비동기 Callback 순서 제어

callback함수로 비동기 순서를 제어할 수 있다.

console.log("A")가 실행되고 나서 다음 함수로 넘어간다.


✅ Promise

비동기적으로 동작하는 함수를 제어가능한 생성자 🔗

new Promise((resolve[,reject]) => {
	function(resolve())  // 비동기 작업이 성공한 경우 resolve 메서드가 .then 호출
    })
    .then(() => {})  //.then 뒤에는 익명함수

 

Promise의 세가지 상태

1. pending (대기) 

2. fulfilled (이행) : 연산 성공적으로 완료

3. rejected (거부) : 연산 실패

 


 

Promise.resolve() 🔗

Promise.resolve(value);

 resolve()의 전달인자

: then의 콜백함수가 받을 수 있다

 

resolve()의 리턴 값

: Promise.then 객체를 리턴

 


.then 🔗

resolve()가 리턴하는 메서드

p.then(onFulfilled, onRejected);

p.then(function(value) {
  // 이행
}, function(reason) {
  // 거부
});

✔ .then의 전달인자

: Promise가 이행했을 때의 콜백함수, 거부했을 때의 콜백함수 

=> 이 콜백함수의 전달인자는 1개이다

 

.then의 리턴 값

: Promise를 리턴

 

(1) 실행된 콜백함수가 값을 리턴

.then이 반환한 Promise : fulfilled 

.then이 반환한 Promise 결과 값 : 콜백함수 리턴 값

 

(2) 실행된 콜백함수가 Promise를 리턴

.then이 반환한 Promise === 콜백함수가 반환한 Promise (상태를 따라가짐)

Promise chain 생성

 

(3) 실행된 콜백함수가 아무 값도 리턴하지 않음

.then이 반환한 Promise : fulfilled 

.then이 반환한 Promise 결과 값 : undefined

 

(4) 실행된 콜백함수가 에러 발생

.then이 반환한 Promise : rejected

.then이 반환한 Promise 결과 값 : 해당 에러 객체

 

(5) 아무런 콜백함수가 실행되지 않음 

.then이 반환한 Promise === 이전 Promise

.then이 반환한 Promise 결과 값 === 이전 Promise 결과 값

 

🔗then 메소드 완벽하게 이해하기


 

✔ .catch 🔗

:Promise가 reject될 때 이행되는 메서드

p.catch(onRejected)

p.catch(function(reason) {})

.then은 Promise가 이행될 때와 거부될 때 사용 가능하지만

.catch는 거부될 때만 사용 가능

 

.catch의 콜백함수의 전달인자 reason : 오류 내용

 


✔ Promise.all 🔗

Promise.all(iterable);

iterable : 배열과 같이 순회 가능한 객체

객체 내의 모든 Promise들을 이행

하나의 Promise라도 거부되면, 나머지 Promise들도 같은 이유로 거부한다.

 

 

callback hell에서 벗어나기 위해 Promise를 사용했지만 적절한 return을 하지 않는 경우 Promise hell이 생길 수 있다.

또 Promise는 .then(() => {}) 이 부분이 지저분하다는 단점이 있다

✔ Promise hell


✅ async, await

비동기 함수로 동작하지만, 동기처럼 코드를 작성할 수 있음

 

✔ 실행방식

async식에는 await가 포함될 수 있는데, 이때 await는 async 함수의 실행을 일시중지한다.

이후 전달된 Promise의 해결을 기다린 다음, async 함수를 다시 시작하고 값을 반환한다.

 

✔특징

1. async 함수는 항상 Promise를 반환

2. await는 async 함수 내에서만 동작

3. await를 변수에 할당할 수 있음

async function foo() {
        await 1
    }
 function foo() {
        return Promise.resolve(1).then((num) => {num})
    }

둘은 같은 코드이다.

.then에 리턴값이 없다면 undefined가 나오는 것처럼 await도 똑같이 행동한다.

await가 Promise chain을 생성했다.