개념정리

동기

호이스팅이 된 다음, 작성한 코드들이 차례대로 실행되는 것을 말한다.
( hoisting : 변수, 함수 선언이 가장 먼저 실행되는 것 )

비동기

코드 순서에 따르지 않고 실행되는 것으로,
setTimeout / AJAX / eventListener 등의 처리 시 비동기 처리 된다.

콜백함수

실행할때 다시 call back 해달라고 하는 함수. 함수 안에서 동작하는 또 다른 함수의 형태.
콜백함수로 동기 / 비동기 처리 모두 할 수 있다.

  • Synchronous callback : 함수 내 코드가 바로 실행될 수 있는 코드인 경우
  • Asynchronous callback : 함수 내 코드가 실행 타이밍을 기다려야하는 코드인 경우

콜백함수의 중첩이 많아지면 가독성이 떨어지고 복잡해지므로, promise 문법을 사용하면 좋다.



promise 사용하기

주로 비동기 처리를 위해 콜백함수를 사용하는 대신, 더 좋은 코드를 만들기 위해 promise 문법을 사용한다.
Promise is a Jacascript object for asynchronous operation.



promise 사용 시 알아야 할 포인트

state

프로세스가 기능 수행 중인지, 수행을 완료해서 성공인지, 실패인지 상태를 확인하는 것
pending (기능 수행 중) > fulfilled (완료) or rejected (거절)

producer & consumer

promise를 선언하는 것은 producer 코드이고
만들어진 promise를 사용하는 것은 consumer 코드이다.



producer

1
2
3
4
5
6
7
8
function promiseName() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve("work done successfully");
      // reject(new Error("didnt work"));
    }, 2000);
  });
}

시간이 조금 걸리는 일들은, 프로세스 완료 후에 순차적으로 기능을 실행하기 위해서 promise를 만든다.

만약 데이터를 받아오는데 시간이 걸리는 코드가 있는데,
화면에 UI를 표시하는 동기적 코드가 먼저 실행된다면 사용자는 내용이 빈 화면을 보게 될 수 있다.
안정적으로 데이터가 다 온 다음 내용을 화면에 표시해줄 수 있도록 하는 비동기 처리 함수가 필요한 것이다.

💡
producer는 선언된 순간 작업을 시작한다.
페이지를 오픈하자마자 데이터를 요청해야하는 경우는 상관없지만,
사용자가 버튼을 눌러서 데이터를 요청해야하는 경우라면 불필요한 데이터 요청 작업이 일어날 수 있으므로 주의해야한다.

💡
promise를 선언하는것은, 프로세스가 성공했는지 실패했는지 판정하게 하기 위함이다.
resolve () 함수를 통해 프로세스 성공 시 받아올 리턴값을 설정할 수 있고,
reject (new Error()) 함수를 통해 프로세스 실패 시 받아올 리턴값을 설정할 수 있다.

💡
promise는 비동기 처리를 위한 코드를 가독성 좋게 디자인하기 위함이지 (this is just coding style),
동기처리 되는 코드를 비동기처리 할 수 있도록 만드는 문법이 아니다.


😓
promise를 이해하기위해 많은 글과 강의를 찾아봤는데 promise를 조금씩 다르게 선언하더라..

1
2
3
4
5
6
7
8
9
10
11
// 1
const promiseName = new Promise((resolve, reject) => {
  //
});

// 2
function promiseName(value) {
  return new Promise((resolve, reject) => {
    //
  });
}

이 두가지 경우가 어떻게 다른지 모르겠다 ㅠㅠ


아!! 오픈챗 선생님들께 여쭤봐서 답을 찾았다!
var functionName = function() {} vs function functionName() {}
이건 promise를 떠나서 hoisting의 문제였다.

1
2
3
4
5
6
functionOne();

var functionOne = function () {
  console.log("Hello!");
};
// TypeError: functionOne is not a function
1
2
3
4
5
6
functionTwo();

function functionTwo() {
  console.log("Hello!");
}
// Outputs: "Hello!"

변수로 선언하는 경우, 변수 코드가 실행될 순서가 되었을 때 실행된다.
함수로 선언하는 경우, 페이지가 열리자마자 호이스팅되어 먼저 정의되기 때문에,
함수코드가 뒤쪽에 있더라도 자유롭게 사용 가능하다.
고로 함수로 선언해 사용하는 것이 안정적이겠다.



consumer

1
2
3
4
5
6
7
8
9
10
promise
  .then((value) => {
    console.log(value); // output : work done successfully
  })
  .catch((value) => {
    console.log(value); // output : didnt work
  })
  .finally(() => {
    console.log("done");
  });

.then 프로세스 성공
.catch 프로세스 실패
.finally 성공 여부에 관계없이 마지막에 실행
만들어 놓은 promise를 이용해서 리턴값을 받아와 3가지 메소드를 붙여 실행할 수 있다.

만약 promise 함수에 reject 값이 설정되어있는데 catch 메소드를 사용하지 않으면 에러가 발생한다.



promise chaining

promise를 사용하면 함수 속에 함수, 또 함수 속에 함수를 넣지 않고
순차적으로 실행되어야 하는 코드를 병렬로 펼칠 수 있다.

1
2
3
4
5
6
7
8
promiseName()
  .then((result) => {
    console.log(result); // 작업 수행 후
    return promiseName(); // 다음 작업에 넘겨줄 내용
  })
  .then((result) => {
    console.log(result); // 넘어온 내용을 받아서 실행
  });



[참고글]
자바스크립트 Promise 쉽게 이해하기
바보들을 위한 Promise 강의
비동기처리 - Promise
콜백지옥 대신 Promise

Leave a comment