JavaScript 18장 - 개념짚기 (12)
포스트
취소

JavaScript 18장 - 개념짚기 (12)

JavaScript

promise

1
2
3
const pr = new Promise((resolve, reject) => {
  // 실행코드
});
  • 우리가 어떤 것을 주문했을 때, 그것이 완료되기까지 시간이 걸리고 완료 후 주문자에게 완료되는 것을 전달하는 것을 promise라고 부른다.
  • 성공했을 때와 실패했을 때가 나뉘며, 어떤 일이 완료됐을 때 실행되는 콜백함수를 넘겨준다.
1
2
3
4
5
6
7
8
9
10
11
new Promise();
state: pending(대기);
result: undefined;

// resolve(value) 성공 시
state: fulfilled(이행됨);
result: value;

// reject(error) 실패 시
state: rejected(거부됨);
result: error;
  • 실행 후 반환되는 결과를 주문한 사람에게 넘겨주듯이 똑같이 then을 사용하여 처리할 수 있다.
  • 첫 번째 인자로는 성공했을 때 실행되는 함수를, 두 번째 인자로는 실패했을 때 실행되는 함수를 넣어준다.
  • 성공하거나 실패했을 때에 또 다른 함수는 실행되지 않는다.
  • 가독성을 위해 실패했을 때를 명확히 구분지어 catch문을 사용하여 에러 발생 시를 구분 짓는 것이 좋다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const pr = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("OK");
  }, 3000);
});

pr.then(
  function (result) {
    console.log(result + "가지러 가자");
  },
  function (err) {
    console.log("다시 주문해주세요");
  }
);
// catch
pr.then(function(result){console.log(result + "가지러 가자");})
.catch(function(err))
  • finally는 실행 및 실패 후 항상 실행된다.

callback hell

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
const f1 = function () {
  setTimeout(function () {
    console.log("1번 주문 완료");
  }, 1000);
};

const f2 = function () {
  setTimeout(function () {
    console.log("2번 주문 완료");
  }, 1000);
};

const f3 = function () {
  setTimeout(function () {
    console.log("3번 주문 완료");
  }, 1000);
};

console.log("시작");
f1(function () {
  f2(function () {
    f3(function () {
      console.log("");
    });
  });
});
  • promise 없이 위 코드를 실행 시, 계속 콜백함수를 불러와야 하며, 이 코드가 깊어지며 callback hell을 만든다.
  • 이를 promise로 처리한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
const f1 = () => {
  return new Promise((res, rej) => {
    setTimeout(() => {
      res("1번 주문 완료");
    }, 1000);
  });
};

const f2 = (message) => {
  console.log(message);
  return new Promise((res, rej) => {
    setTimeout(() => {
      res("2번 주문 완료");
    }, 1000);
  });
};

const f3 = (message) => {
  console.log(message);
  return new Promise((res, rej) => {
    setTimeout(() => {
      res("3번 주문 완료");
    }, 1000);
  });
};

console.log("시작");
f1()
  .then((res) => f2(res))
  .then((res) => f3(res))
  .then((res) => console.log(res))
  .catch(console.log)
  .finally(() => {
    console.log("");
  });
  • 위처럼 promise가 연결되어 있는 것을 프로미스 체이닝(Promise chaining)이라고 한다.

Promise.all

  • 여러 개의 promise를 함께 처리한다.
  • 배열을 받고 then으로 처리할 수 있으며, 한꺼번에 시작한다.
  • 하나의 정보라도 누락되면 모든 것이 누락되기 때문에 주의해야 한다.
    • f1reject로 실행하면 f2,f3가 모두 실행되지 않는다.
  • 모든 정보가 누락되지 않아야 할 때도 유용하게 사용된다.
1
Promise.all([f1(), f2(), f3()]).then((res) => console.log(res));

Promise.race

  • all은 모든 작업이 완료되어야 하지만, race는 하나라도 완료되면 실행된다.
  • 사용 방법은 all과 같다.
  • 이미지를 로딩할 때와 같이 하나라도 완료되면 로딩되도록 사용할 때 사용된다.

async await

  • Promise.then을 사용하여 코드가 끝나고 나서야 실행하였던 것과 같다.
  • 함수에 사용되며 async가 사용된 함수에 await를 사용하여 코드가 끝날 때까지 기다릴 수 있다.
  • Promise가 반복되는 상황에서 가독성이 높은 코드를 작성할 수 있으며 에러 발생에 대해서는 try...catch문으로 작성한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
const f1 = (message) => {
  return new Promise((res, rej) => {
    setTimeout(() => {
      res(res + "주문완료");
    }, 2000);
  });
};

const f2 = (message) => {
  return new Promise((res, rej) => {
    setTimeout(() => {
      rej(new Error("err..."));
    }, 2000);
  });
};

f1().then((res) => res + "하였습니다.");

// 위 코드와 동일하지만 가독성이 좋다.
async function order() {
  const result = await f1();
  return result;
}

// reject 처리 try...catch
// try를 시도하고 에러가 발생하면 catch문을 실행한다.
async function order2() {
  try {
    const result = await f2();
    return result;
  } catch (e) {
    return e;
  }
}
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.