[JavaScript 비동기] callback, promise

young·2022년 5월 29일
0

5/25~6/22 Section 2 TIL

목록 보기
8/27

(공부 중인 사람의 글입니다)

어떤 개념인지 이해는 되는 것 같은데 아직 실제 코드로 작성하기가 어렵다...

✅ TIL

  • synchronous, asynchronous
  • blocking, non-blocking
  • setTimeout()
  • promise, then, catch, finally
  • async, await

💡 Synchronus / Asynchronous

1. 콜백 함수

: 함수의 전달인자로 넘겨지는 함수

  • 필요에 따라 Synchronous callback / Asynchronous callback으로 실행할 수 있다.

  • 비동기 함수의 순서를 제어하고 싶을 때 callback을 이용한다.

//1. Synchronous callback
function printImmediately(print) {
    print();
}
printImmediately(() => console.log('sync callback')); //동기
//즉시 출력


//2. Asynchronous callback
function printWithDelay(print, timeout) {
    setTimeout(print, timeout)
}
printWithDelay(() => console.log('async callback'), 2000); //비동기
//2초 뒤 출력
  • 콜백 안에 콜백을 작성하는 callback chain이 지나칠 경우 문제점이 생긴다. (로직을 한 눈에 확인하기 어렵다, 가독성이 떨어진다, 디버깅이 어렵다.)
    ---> 효율적인 코드 작성을 위해 promise 사용

2. 타이머 API (비동기 함수)

✔️ setTimeout(callback, ms)

: web API
지정 시간(ms) 후에 callback 함수가 실행된다.

const youngTime = setTimeOut(() => console.log('young'), 1000);
//1초 뒤 young 출력

✔️ clearTimeout(timerId)

setTimeout 타이머를 종료한다.

clearTimeout(youngTime);

✔️ setInterval(callback, ms)

지정 시간의 간격으로 callback함수를 반복적으로 실행한다.

const sayHi = setTimeout(() => console.log('Hi!'), 2000);
//2초마다 Hi! 출력

✔️ clearInterval(timerId)

setInterval 타이머를 종료한다.

clearInterval(sayHi);

3. blocking / non-blocking

✔️ blocking

: 하던 일이 끝나고 다음 일을 시작한다.
요청에 대한 결과가 동시에 일어난다.
일에 대한 순차적 실행 (synchronous)

✔️ non-blocking

: 요청에 대한 결과가 동시에 일어나지 않고 딜레이 된다.
요청에 blocking이 없다.
응답이 비동기적으로 이루어진다. (asynchronous)


4. 비동기 주요 사례

  • DOM elemnet의 event Handler
  • 타이머 API, 애니메이션 API
  • fetch API, AJAX (XHR) 등


💡 Promise

: JavaScript asynchronous operation에서 콜백함수 대신에 사용할 수 있는 object

Promise는 비동기 작업의 최종 완료 또는 실패를 나타내는 객체입니다. 기본적으로 promise는 함수에 콜백을 전달하는 대신에, 콜백을 첨부하는 방식의 객체입니다. -mdn


1. state

: promise의 실행 상태

수행중일 때 pending
완료되면 fulfilled
오류가 있으면 rejected


2. Producer

프로미스를 만든 순간부터 "executor runs automatically"
성공할 경우 resolve(...)을 호출하고, 실패할 경우 reject(...)을 호출한다.

const firstPromise = new Promise((resolve, reject) => {
    //doing some heavy work (network, read files)
    console.log('doing something...');
    setTimeout(() => {
        resolve('youngs velog')
    }, 2000)
});

const secondPromise = (string) => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log(string)
      resolve()
    },1000)
  })
};

3. Consumers

firstPromise.then(console.log)
>youngs velog //2초 뒤 출력

const printAll = () => {
  secondPromise('hi')
  .then(() => {
    return secondPromise('hi!!')
  })
  .then(() => {
    return secondPromise('hi!!!')
  })
}
printAll()

✔️.then()

  • 다음 task로 넘어갈 수 있게 한다.

  • promise가 정상적으로 수행된다면 resolve에서 가져온 value가 parameter로 들어온다. (성공적인 케이스를 다룬다.)

.then(resolve에서 가져온 value에 대해 실행할 함수)

firstPromise()
  .then(value => {
  console.log(value)
  return nextPromise()
});

✔️ .catch()

  • error 케이스를 다룬다.

  • 마지막 promise chain 뒤에, 또는 원하는 task 바로 뒤에 작성하여 에러에 대응할 수 있다.

.catch(error => {...})

promise()
  .then(...)
  .catch(error=> {
  console.log(error)
});

✔️ .finally()

promise.finally
:성공, 실패와 상관 없이 마지막에 이루어지는 기능
promise.finally (() => {console.log('finally')};

✔️ async , await (syntactic sugar)

async :function 앞에 작성하여 function을 promise로 변환해준다.

const result = async () => {...}

async function result() {...}

await: promise를 동기적으로 실행되는 것처럼 보이게 한다.
해당 promise가 종료된 후에 다음 내용을 실행한다.

const result = async () => {
  const one = await firstPromise();
  console.log(one);
  ...
}
  result();

Learn more...

Promise.all([함수, 함수2 ...]) :병렬적으로 연결
Promise.race([함수, 함수1...]) : 가장 먼저 수행이 끝나는 함수 출력

profile
즐겁게 공부하고 꾸준히 기록하는 나의 프론트엔드 공부일지

0개의 댓글