πŸ΄β€β˜ οΈ 45.1 비동기 처리λ₯Ό μœ„ν•œ 콜백 νŒ¨ν„΄μ˜ 단점

βœ” 45.1.1 콜백 ν—¬

비동기 ν•¨μˆ˜λž€ ν•¨μˆ˜ 내뢀에 λΉ„λ™κΈ°λ‘œ λ™μž‘ν•˜λŠ” μ½”λ“œλ₯Ό ν¬ν•¨ν•œ ν•¨μˆ˜λ₯Ό λ§ν•œλ‹€. 비동기 ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜λ©΄ ν•¨μˆ˜ λ‚΄λΆ€μ˜ λΉ„λ™κΈ°λ‘œ λ™μž‘ν•˜λŠ” μ½”λ“œκ°€ μ™„λ£Œλ˜μ§€ μ•Šμ•˜λ‹€ 해도 기닀리지 μ•Šκ³  μ¦‰μ‹œ μ’…λ£Œλœλ‹€. 즉, 비동기 ν•¨μˆ˜ λ‚΄λΆ€μ˜ λΉ„λ™κΈ°λ‘œ λ™μž‘ν•˜λŠ” μ½”λ“œλŠ” 비동기 ν•¨μˆ˜κ°€ μ’…λ£Œλœ 이후에 μ™„λ£Œλœλ‹€. λ”°λΌμ„œ 비동기 ν•¨μˆ˜ λ‚΄λΆ€μ˜ λΉ„λ™κΈ°λ‘œ λ™μž‘ν•˜λŠ” μ½”λ“œμ—μ„œ 처리 κ²°κ³Όλ₯Ό μ™ΈλΆ€λ‘œ λ°˜ν™˜ν•˜κ±°λ‚˜ μƒμœ„ μŠ€μ½”ν”„μ˜ λ³€μˆ˜μ— ν• λ‹Ήν•˜λ©΄ κΈ°λŒ€ν•œ λŒ€λ‘œ λ™μž‘ν•˜μ§€ μ•ŠλŠ”λ‹€.

// GET μš”μ²­μ„ μœ„ν•œ 비동기 ν•¨μˆ˜
const get = url => {
  const xhr = new XMLHttpRequest();
  xhr.open('GET', url);
  xhr.send();

  xhr.onload = () => {
    if (xhr.status === 200) {
      // μ„œλ²„μ˜ 응닡을 μ½˜μ†”μ— 좜λ ₯ν•œλ‹€.
      console.log(JSON.parse(xhr.response));
    } else {
      console.error(`${xhr.status} ${xhr.statusText}`);
    }
  };
};

// idκ°€ 1인 postλ₯Ό 취득
get('https://jsonplaceholder.typicode.com/posts/1');
/*
{
  "userId": 1,
  "id": 1,
  "title": "sunt aut facere ...",
  "body": "quia et suscipit ..."
}
*/
let g = 0;

// 비동기 ν•¨μˆ˜μΈ setTimeout ν•¨μˆ˜λŠ” 콜백 ν•¨μˆ˜μ˜ 처리 κ²°κ³Όλ₯Ό μ™ΈλΆ€λ‘œ λ°˜ν™˜ν•˜κ±°λ‚˜
// μƒμœ„ μŠ€μ½”ν”„μ˜ λ³€μˆ˜μ— ν• λ‹Ήν•˜μ§€ λͺ»ν•œλ‹€.
setTimeout(() => { g = 100; }, 0);
console.log(g); // 0
console.log(g);

πŸ΄β€β˜ οΈ 45.2 ν”„λ‘œλ―ΈμŠ€μ˜ 생성

Promise μƒμ„±μž ν•¨μˆ˜λ₯Ό new μ—°μ‚°μžμ™€ ν•¨κ»˜ ν˜ΈμΆœν•˜λ©΄ ν”„λ‘œλ―ΈμŠ€(Promise 객체)λ₯Ό μƒμ„±ν•œλ‹€. Promise μƒμ„±μž ν•¨μˆ˜λŠ” 비동기 처리λ₯Ό μˆ˜ν–‰ν•  μ½œλ°±ν•¨μˆ˜λ₯Ό 인수둜 μ „λ‹¬λ°›λŠ”λ° 이 μ½œλ°±ν•¨μˆ˜λŠ” resolve와 reject ν•¨μˆ˜λ₯Ό 인수둜 μ „λ‹¬λ°›λŠ”λ‹€.

// ν”„λ‘œλ―ΈμŠ€ 생성
const promise = new Promise((resolve, reject) => {
  // Promise ν•¨μˆ˜μ˜ 콜백 ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œ 비동기 처리λ₯Ό μˆ˜ν–‰ν•œλ‹€.
  if (/* 비동기 처리 성곡 */) {
    resolve('result');
  } else { /* 비동기 처리 μ‹€νŒ¨ */
    reject('failure reason');
  }
});

Promise μƒμ„±μž ν•¨μˆ˜κ°€ 인수둜 전달받은 콜백 ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œ 비동기 처리λ₯Ό μˆ˜ν–‰ν•œλ‹€. μ΄λ•Œ 비동기 μ²˜λ¦¬κ°€ μ„±κ³΅ν•˜λ©΄ μ½œλ°±ν•¨μˆ˜μ˜ 인수둜 전달받은 resolve ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜κ³ , 비동기 μ²˜λ¦¬κ°€ μ‹€νŒ¨ν•˜λ©΄ reject ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•œλ‹€.

ν”„λ‘œλ―ΈμŠ€λŠ” λ‹€μŒκ³Ό 같이 ν˜„μž¬ 비동기 μ²˜λ¦¬κ°€ μ–΄λ–»κ²Œ μ§„ν–‰λ˜κ³  μžˆλŠ”μ§€λ₯Ό λ‚˜νƒ€λ‚΄λŠ” μƒνƒœ(state) 정보λ₯Ό κ°–λŠ”λ‹€.

ν”„λ‘œλ―ΈμŠ€ μƒνƒœ μ •λ³΄μ˜λ―Έμƒνƒœ λ³€κ²½ 쑰건
pending비동기 μ²˜λ¦¬κ°€ 아직 μˆ˜ν–‰λ˜μ§€ μ•Šμ€ μƒνƒœν”„λ‘œλ―ΈμŠ€κ°€ μƒμ„±λœ 직후 κΈ°λ³Έ μƒνƒœ
fulfilled비동기 μ²˜λ¦¬κ°€ μˆ˜ν–‰λœ μƒνƒœ(성곡)resolve ν•¨μˆ˜ 호좜
rejected비동기 μ²˜λ¦¬κ°€ μˆ˜ν–‰λœ μƒνƒœ(μ‹€νŒ¨)reject ν•¨μˆ˜ 호좜

μƒμ„±λœ μ§ν›„μ˜ ν”„λ‘œλ―ΈμŠ€λŠ” 기본적으둜 pending μƒνƒœλ‹€. 이후 비동기 μ²˜λ¦¬κ°€ μˆ˜ν–‰λ˜λ©΄ 비동기 처리 결과에 따라 λ‹€μŒκ³Ό 같이 ν”„λ‘œλ―ΈμŠ€μ˜ μƒνƒœκ°€ λ³€κ²½λœλ‹€.

  • 비동기 처리 성곡 : resolve ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•΄ ν”„λ‘œλ―ΈμŠ€λ₯Ό fulfilled μƒνƒœλ‘œ λ³€κ²½ν•œλ‹€.
  • 비동기 처리 μ‹€νŒ¨ : reject ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•΄ ν”„λ‘œλ―ΈμŠ€λ₯Ό rejected μƒνƒœλ‘œ λ³€κ²½ν•œλ‹€.

이처럼 ν”„λ‘œλ―ΈμŠ€μ˜ μƒνƒœλŠ” resolve λ˜λŠ” reject ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜λŠ” κ²ƒμœΌλ‘œ κ²°μ •λœλ‹€.

fulfilled λ˜λŠ” rejected μƒνƒœλ₯Ό settled μƒνƒœλΌκ³  ν•œλ‹€. settle μƒνƒœλŠ” fulfilled λ˜λŠ” reject μƒνƒœμ™€ 상관없이 pending이 μ•„λ‹Œ μƒνƒœλ‘œ 비동기 μ²˜λ¦¬κ°€ μˆ˜ν–‰λœ μƒνƒœλ₯Ό λ§ν•œλ‹€.

ν”„λ‘œλ―ΈμŠ€λŠ” pending μƒνƒœμ—μ„œ fulfilled λ˜λŠ” rejected μƒνƒœ, 즉 settled μƒνƒœλ‘œ λ³€ν™”ν•  수 μžˆμ§€λ§Œ settled μƒνƒœκ°€ 되면 λ”λŠ” λ‹€λ₯Έ μƒνƒœλ‘œ λ³€ν™”ν•  수 μ—†λ‹€.

❗ κ²°λ‘ 
ν”„λ‘œλ―ΈμŠ€λŠ” 비동기 처리 μƒνƒœμ™€ 처리 κ²°κ³Όλ₯Ό κ΄€λ¦¬ν•˜λŠ” 객체닀.


πŸ΄β€β˜ οΈ 45.3 ν”„λ‘œλ―ΈμŠ€μ˜ 후속 처리 λ©”μ„œλ“œ

ν”„λ‘œλ―ΈμŠ€λŠ” 비동기 처리 μƒνƒœλ³€ν™”μ— λ”°λ₯Έ 후속 처리λ₯Ό ν•˜κΈ° μœ„ν•΄ 후속 λ©”μ„œλ“œ then, catch, finallyλ₯Ό μ œκ³΅ν•œλ‹€.

ν”„λ‘œλ―ΈμŠ€μ˜ 비동기 처리 μƒνƒœκ°€ λ³€ν™”ν•˜λ©΄ 후속 처리 λ©”μ„œλ“œμ— 인수둜 μ „λ‹¬ν•œ 콜백 ν•¨μˆ˜κ°€ μ„ νƒμ μœΌλ‘œ ν˜ΈμΆœλœλ‹€. 이 λ•Œ 후속 처리 λ©”μ„œλ“œμ˜ 콜백 ν•¨μˆ˜μ— ν”„λ‘œλ―ΈμŠ€μ˜ 처리 κ²°κ³Όκ°€ 인수둜 μ „λ‹¬λœλ‹€. λͺ¨λ“  후속 처리 λ©”μ„œλ“œλŠ” ν”„λ‘œλ―ΈμŠ€λ₯Ό λ°˜ν™˜ν•˜λ©°, λΉ„λ™κΈ°λ‘œ λ™μž‘ν•œλ‹€. ν”„λ‘œλ―ΈμŠ€μ˜ 후속 처리 λ©”μ„œλ“œλŠ” λ‹€μŒκ³Ό κ°™λ‹€.

βœ” 45.3.1 Promise.prototype.then

then λ©”μ„œλ“œλŠ” 두 개의 콜백 ν•¨μˆ˜λ₯Ό 인수둜 μ „λ‹¬λ°›λŠ”λ‹€.

  • 첫 번째 μ½œλ°±ν•¨μˆ˜λŠ” ν”„λ‘œλ―ΈμŠ€κ°€ fulfilled μƒνƒœκ°€ 되면 ν˜ΈμΆœλœλ‹€. ν”„λ‘œλ―ΈμŠ€μ˜ 비동기 처리 κ²°κ³Όλ₯Ό 인수둜 μ „λ‹¬λ°›λŠ”λ‹€.
  • 두 번째 μ½œλ°±ν•¨μˆ˜λŠ” ν”„λ‘œλ―ΈμŠ€κ°€ rejected μƒνƒœκ°€ 되면 ν˜ΈμΆœλœλ‹€. ν”„λ‘œλ―ΈμŠ€μ˜ μ—λŸ¬λ₯Ό 인수둜 μ „λ‹¬λ°›λŠ”λ‹€.
// fulfilled
new Promise(resolve => resolve('fulfilled'))
  .then(v => console.log(v), e => console.error(e)); // fulfilled

// rejected
new Promise((_, reject) => reject(new Error('rejected')))
  .then(v => console.log(v), e => console.error(e)); // Error: rejected

βœ” 45.3.2 Promise.prototype.catch

catch λ©”μ„œλ“œλŠ” ν•œ 개의 콜백 ν•¨μˆ˜λ₯Ό 인수둜 μ „λ‹¬λ°›λŠ”λ‹€. catch λ©”μ„œλ“œμ˜ 콜백 ν•¨μˆ˜λŠ” ν”„λ‘œλ―ΈμŠ€κ°€ rejected μƒνƒœμΈ 경우만 ν˜ΈμΆœλœλ‹€. catch λ©”μ„œλ“œλŠ” thenκ³Ό λ™μΌν•˜κΈ° λ™μž‘ν•œλ‹€.

// rejected
new Promise((_, reject) => reject(new Error('rejected')))
  .then(undefined, e => console.log(e)); // Error: rejected

βœ” 45.3.3 Promise.prototype.finally

finally λ©”μ„œλ“œλŠ” ν•œ 개의 콜백 ν•¨μˆ˜λ₯Ό 인수둜 μ „λ‹¬λ°›λŠ”λ‹€. finally λ©”μ„œλ“œμ˜ 콜백 ν•¨μˆ˜λŠ” ν”„λ‘œλ―ΈμŠ€μ˜ 성곡(fulfilled) λ˜λŠ” μ‹€νŒ¨(rejected)와 상관없이 무쑰건 ν•œ 번 ν˜ΈμΆœλœλ‹€. finally λ©”μ„œλ“œλŠ” ν”„λ‘œλ―ΈμŠ€μ˜ μƒνƒœμ™€ 상관 없이 κ³΅ν†΅μ μœΌλ‘œ μˆ˜ν–‰ν•΄μ•Ό ν•  처리 λ‚΄μš©μ΄ μžˆμ„ λ•Œ μœ μš©ν•˜λ‹€.

new Promise(() => {})
  .finally(() => console.log('finally')); // finally
const promiseGet = url => {
  return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest();
    xhr.open('GET', url);
    xhr.send();

    xhr.onload = () => {
      if (xhr.status === 200) {
        // μ„±κ³΅μ μœΌλ‘œ 응닡을 μ „λ‹¬λ°›μœΌλ©΄ resolve ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•œλ‹€.
        resolve(JSON.parse(xhr.response));
      } else {
        // μ—λŸ¬ 처리λ₯Ό μœ„ν•΄ reject ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•œλ‹€.
        reject(new Error(xhr.status));
      }
    };
  });
};

// promiseGet ν•¨μˆ˜λŠ” ν”„λ‘œλ―ΈμŠ€λ₯Ό λ°˜ν™˜ν•œλ‹€.
promiseGet('https://jsonplaceholder.typicode.com/posts/1')
  .then(res => console.log(res))
  .catch(err => console.error(err))
  .finally(() => console.log('Bye!'));

πŸ΄β€β˜ οΈ 45.4 ν”„λ‘œλ―ΈμŠ€μ˜ μ—λŸ¬ 처리

비동기 μ²˜λ¦¬μ—μ„œ λ°œμƒν•œ μ—λŸ¬λŠ” λ‹€μŒκ³Ό 같이 μ—λŸ¬ μ²˜λ¦¬ν•œλ‹€.

promiseGet('https://jsonplaceholder.typicode.com/todos/1')
  .then(res => console.xxx(res))
  .catch(err => console.error(err)); // TypeError: console.xxx is not a function

πŸ΄β€β˜ οΈ 45.5 ν”„λ‘œλ―ΈμŠ€ 체이닝

then, catch, finally 후속 처리 λ©”μ„œλ“œλŠ” μ–Έμ œλ‚˜ ν”„λ‘œλ―ΈμŠ€λ₯Ό λ°˜ν™˜ν•˜λ―€λ‘œ μ—°μ†μ μœΌλ‘œ ν˜ΈμΆœν•  수 μžˆλ‹€. 이λ₯Ό ν”„λ‘œλ―ΈμŠ€ 체이닝이라 ν•œλ‹€.

ν”„λ‘œλ―ΈμŠ€λŠ” ν”„λ‘œλ―ΈμŠ€ 체이닝을 톡해 비동기 처리 κ²°κ³Όλ₯Ό 전달받아 후속 처리λ₯Ό ν•˜λ―€λ‘œ 비동기 처리λ₯Ό μœ„ν•œ 콜백 νŒ¨ν„΄μ—μ„œ λ°œμƒν•˜λ˜ 콜백 헬이 λ°œμƒν•˜μ§€ μ•ŠλŠ”λ‹€. ν•˜μ§€λ§Œ 가독성이 쒋지 μ•ŠμœΌλ―€λ‘œ async와 awaitλ₯Ό μ‚¬μš©ν•΄ ν”„λ‘œλ―ΈμŠ€μ˜ 후속 처리 λ©”μ„œλ“œ 없이 마치 동기 처리처럼 ν”„λ‘œλ―ΈμŠ€κ°€ 처리 κ²°κ³Όλ₯Ό λ°˜ν™˜ν•˜λ„λ‘ κ΅¬ν˜„ν•  수 μžˆλ‹€.

πŸ΄β€β˜ οΈ 45.6 ν”„λ‘œλ―ΈμŠ€μ˜ 정적 λ©”μ„œλ“œ

PromiseλŠ” 주둜 μƒμ„±μž ν•¨μˆ˜λ‘œ μ‚¬μš©λ˜μ§€λ§Œ ν•¨μˆ˜λ„ κ°μ²΄μ΄λ―€λ‘œ λ©”μ„œλ“œλ₯Ό κ°€μ§ˆ 수 μžˆλ‹€. PromiseλŠ” 5가지 정적 λ©”μ„œλ“œλ₯Ό μ œκ³΅ν•œλ‹€.

βœ” 45.6.1 Promise.resolve/Promise.reject

Promise.resolve/Promise.reject λ©”μ„œλ“œλŠ” 이미 μ‘΄μž¬ν•˜λŠ” 값을 λž˜ν•‘ν•˜μ—¬ ν”„λ‘œλ―ΈμŠ€λ₯Ό μƒμ„±ν•˜κΈ° μœ„ν•΄ μ‚¬μš©ν•œλ‹€.

// 배열을 resolveν•˜λŠ” ν”„λ‘œλ―ΈμŠ€λ₯Ό 생성
const resolvedPromise = Promise.resolve([1, 2, 3]);
resolvedPromise.then(console.log); // [1, 2, 3]
// μœ„ μ˜ˆμ œλŠ” μ•„λž˜ μ˜ˆμ œμ™€ λ™μΌν•˜κ²Œ λ™μž‘ν•œλ‹€.
const resolvedPromise = new Promise(resolve => resolve([1, 2, 3]));
resolvedPromise.then(console.log); // [1, 2, 3]
// μ—λŸ¬ 객체λ₯Ό rejectν•˜λŠ” ν”„λ‘œλ―ΈμŠ€λ₯Ό 생성
const rejectedPromise = Promise.reject(new Error('Error!'));
rejectedPromise.catch(console.log); // Error: Error!
// μœ„ μ˜ˆμ œλŠ” μ•„λž˜ μ˜ˆμ œμ™€ λ™μΌν•˜κ²Œ λ™μž‘ν•œλ‹€.
// μ—λŸ¬ 객체λ₯Ό rejectν•˜λŠ” ν”„λ‘œλ―ΈμŠ€λ₯Ό 생성
const rejectedPromise = Promise.reject(new Error('Error!'));
rejectedPromise.catch(console.log); // Error: Error!

βœ” 45.6.2 Promiss.all

Promiss.all λ©”μ„œλ“œλŠ” μ—¬λŸ¬ 개의 비동기 처리λ₯Ό λͺ¨λ‘ 병렬 μ²˜λ¦¬ν• λ•Œ μ‚¬μš©ν•œλ‹€.

const requestData1 = () => new Promise(resolve => setTimeout(() => resolve(1), 3000));
const requestData2 = () => new Promise(resolve => setTimeout(() => resolve(2), 2000));
const requestData3 = () => new Promise(resolve => setTimeout(() => resolve(3), 1000));

// μ„Έ 개의 비동기 처리λ₯Ό 순차적으둜 처리
const res = [];
// 3초 뒀에 resolve μˆ˜ν–‰([]빈 배열에 data둜 전달받은 1을 λ„£μŒ κ·Έλ‹€μŒμ—)
// 2초 뒀에 resolve μˆ˜ν–‰([1]배열에 data둜 전달받은 2을 λ„£μŒ κ·Έλ‹€μŒμ—)
// 1초 뒀에 resolve μˆ˜ν–‰([1, 2]배열에 data둜 전달받은 3을 λ„£μŒ)
// μ½˜μ†”λ‘œκ·Έλ‘œ λ°°μ—΄ res([1, 2, 3]) 좜λ ₯ ν›„ catch둜 μ—λŸ¬ν•Έλ“€λ§
requestData1()
  .then(data => {
    res.push(data);
    return requestData2();
  })
  .then(data => {
    res.push(data);
    return requestData3();
  })
  .then(data => {
    res.push(data);
    console.log(res); // [1, 2, 3] β‡’ μ•½ 6초 μ†Œμš”
  })
  .catch(console.error);

μœ„ μ˜ˆμ œλŠ” μ„Έ 개의 비동기 처리λ₯Ό 순처적으둜 μ²˜λ¦¬ν•˜λ‚˜ μ„œλ‘œ μ˜μ‘΄ν•˜μ§€ μ•Šκ³  κ°œλ³„μ μœΌλ‘œ μˆ˜ν–‰λœλ‹€.

const requestData1 = () => new Promise(resolve => setTimeout(() => resolve(1), 3000));
const requestData2 = () => new Promise(resolve => setTimeout(() => resolve(2), 2000));
const requestData3 = () => new Promise(resolve => setTimeout(() => resolve(3), 1000));

Promise.all([requestData1(), requestData2(), requestData3()])
  .then(console.log) // [ 1, 2, 3 ] β‡’ μ•½ 3초 μ†Œμš”
  .catch(console.error);

Promise.all λ©”μ„œλ“œλŠ” ν”„λ‘œλ―ΈμŠ€λ₯Ό μš”μ†Œλ‘œ κ°–λŠ” λ°°μ—΄ λ“±μ˜ μ΄ν„°λŸ¬λΈ”μ„ 인수둜 전달받아 전달받은 λͺ¨λ“  ν”„λ‘œλ―ΈμŠ€κ°€ λͺ¨λ‘ fulfilled μƒνƒœκ°€ 되면 λͺ¨λ“  처리 κ²°κ³Όλ₯Ό 배열에 μ €μž₯ν•΄ μƒˆλ‘œμš΄ ν”„λ‘œλ―ΈμŠ€λ₯Ό λ°˜ν™˜ν•œλ‹€.

Promise.all λ©”μ„œλ“œλŠ” 인수둜 전달받은 λ°°μ—΄μ˜ ν”„λ‘œλ―ΈμŠ€κ°€ ν•˜λ‚˜λΌλ„ rejected μƒνƒœκ°€ 되면 λ‚˜λ¨Έμ§€ ν”„λ‘œλ―ΈμŠ€κ°€ fulfilled μƒνƒœκ°€ λ˜λŠ”κ²ƒμ„ 기닀리지 μ•Šκ³  μ¦‰μ‹œ μ’…λ£Œλœλ‹€.

Promise.all([
  new Promise((_, reject) => setTimeout(() => reject(new Error('Error 1')), 3000)),
  new Promise((_, reject) => setTimeout(() => reject(new Error('Error 2')), 2000)),
  new Promise((_, reject) => setTimeout(() => reject(new Error('Error 3')), 1000))
])
  .then(console.log)
  .catch(console.log); // Error: Error 3

Promise.all λ©”μ„œλ“œλŠ” 인수둜 전달받은 μ΄ν„°λŸ¬λΈ”μ˜ μš”μ†Œκ°€ ν”„λ‘œλ―ΈμŠ€κ°€ μ•„λ‹Œ 경우 Promist.resolve λ©”μ„œλ“œλ₯Ό 톡해 ν”„λ‘œλ―ΈμŠ€λ‘œ λž˜ν•‘ν•œλ‹€.

βœ” 45.6.3 Promiss.race

Promise.race λ©”μ„œλ“œλŠ” Promise.all λ©”μ„œλ“œμ™€ λ™μΌν•˜κ²Œ ν”„λ‘œλ―ΈμŠ€λ₯Ό μš”μ†Œλ‘œ κ°–λŠ” λ°°μ—΄ λ“±μ˜ μ΄ν„°λŸ¬λΈ”μ„ 인수둜 전달받아 κ°€μž₯ λ¨Όμ € fulfiled μƒνƒœκ°€ 된 ν”„λ‘œλ―ΈμŠ€μ˜ 처리 κ²°κ³Όλ₯Ό resolveν•˜λŠ” μƒˆλ‘œμš΄ ν”„λ‘œλ―ΈμŠ€λ₯Ό λ°˜ν™˜ν•œλ‹€.

Promise.race([
  new Promise(resolve => setTimeout(() => resolve(1), 3000)), // 1
  new Promise(resolve => setTimeout(() => resolve(2), 2000)), // 2
  new Promise(resolve => setTimeout(() => resolve(3), 1000)) // 3
])
  .then(console.log) // 3
  .catch(console.log);

ν”„λ‘œλ―ΈμŠ€κ°€ rejected μƒνƒœκ°€ 되면 Promise.all λ©”μ„œλ“œμ™€ λ™μΌν•˜κ²Œ μ²˜λ¦¬λœλ‹€.

Promise.race([
  new Promise((_, reject) => setTimeout(() => reject(new Error('Error 1')), 3000)),
  new Promise((_, reject) => setTimeout(() => reject(new Error('Error 2')), 2000)),
  new Promise((_, reject) => setTimeout(() => reject(new Error('Error 3')), 1000))
])
  .then(console.log)
  .catch(console.log); // Error: Error 3

βœ” 45.6.4 Promiss.allSettled

Promiss.allSettled λ©”μ„œλ“œλŠ” ν”„λ‘œλ―ΈμŠ€λ₯Ό μš”μ†Œλ‘œ κ°–λŠ” λ°°μ—΄ λ“±μ˜ μ΄ν„°λŸ¬λΈ”μ„ 인수둜 μ „λ‹¬λ°›λŠ”λ‹€. 그리고 전달받은 ν”„λ‘œλ―ΈμŠ€κ°€ λͺ¨λ‘ settled μƒνƒœκ°€ 되면 처리 κ²°κ³Όλ₯Ό λ°°μ—΄λ‘œ λ°˜ν™˜ν•œλ‹€.

Promise.allSettled([
  new Promise(resolve => setTimeout(() => resolve(1), 2000)),
  new Promise((_, reject) => setTimeout(() => reject(new Error('Error!')), 1000))
]).then(console.log);
/*
[
  {status: "fulfilled", value: 1},
  {status: "rejected", reason: Error: Error! at <anonymous>:3:54}
]
*/

Promiss.allSettled λ©”μ„œλ“œκ°€ λ°˜ν™˜ν•œ λ°°μ—΄μ—λŠ” fulfilled λ˜λŠ” rejected μƒνƒœμ™€λŠ” 상관없이 Promise.allSettled λ©”μ„œλ“œκ°€ 인수둜 전달받은 λͺ¨λ“  ν”„λ‘œλ―ΈμŠ€λ“€μ˜ 처리 κ²°κ³Όκ°€ λͺ¨λ‘ 담겨 μžˆλ‹€.

πŸ΄β€β˜ οΈ 45.7 λ§ˆμ΄ν¬λ‘œνƒœμŠ€ν¬ 큐

ν”„λ‘œλ―ΈμŠ€μ˜ 후속 처리 λ©”μ„œλ“œμ˜ μ½œλ°±ν•¨μˆ˜λŠ” νƒœμŠ€ν¬ 큐가 μ•„λ‹ˆλΌ λ§ˆμ΄ν¬λ‘œνƒœμŠ€ν¬ 큐에 μΌμ‹œμ €μž₯λœλ‹€.λ§ˆμ΄ν¬λ‘œνƒœμŠ€ν¬ νλŠ” νƒœμŠ€ν¬νλ³΄λ‹€ μš°μ„ μˆœμœ„κ°€ λ†’λ‹€. 즉, 이벀트 λ£¨ν”„λŠ” 콜 μŠ€νƒμ΄ λΉ„λ©΄ λ¨Όμ € λ§ˆμ΄ν¬λ‘œνƒœμŠ€ν¬ νμ—μ„œ λŒ€κΈ°ν•˜κ³  μžˆλŠ” ν•¨μˆ˜λ₯Ό 가져와 μ‹€ν–‰ν•œλ‹€. 이후 λ§ˆμ΄ν¬λ‘œνƒœμŠ€ν¬ 큐가 λΉ„λ©΄ νƒœμŠ€ν¬ νμ—μ„œ λŒ€κΈ°ν•˜κ³  μžˆλŠ” ν•¨μˆ˜λ₯Ό 가져와 μ‹€ν–‰ν•œλ‹€.

πŸ΄β€β˜ οΈ 45.8 fetch

fetch ν•¨μˆ˜λŠ” XMLHttpRequest 객체와 λ§ˆμ°¬κ°€μ§€λ‘œ HTTP μš”μ²­ 전솑 κΈ°λŠ₯을 μ œκ³΅ν•˜λŠ” ν΄λΌμ΄μ–ΈνŠΈ μ‚¬μ΄λ“œ Web APIλ‹€. fetch ν•¨μˆ˜λŠ” XMLHttpRequest 객체보닀 μ‚¬μš©λ²•μ΄ κ°„λ‹¨ν•˜κ³  ν”„λ‘œλ―ΈμŠ€λ₯Ό μ§€μ›ν•˜κΈ° λ•Œλ¬Έμ— 비동기 처리λ₯Ό μœ„ν•œ 콜백 νŒ¨ν„΄μ˜ λ‹¨μ μ—μ„œ μžμœ λ‘­λ‹€.

fetch ν•¨μˆ˜μ—λŠ” HTTP μš”μ²­μ„ 전솑할 URLκ³Ό HTTP μš”μ²­ λ©”μ„œλ“œ, HTTP μš”μ²­ 헀더, νŽ˜μ΄λ‘œλ“œ 등을 μ„€μ •ν•œ 객체λ₯Ό μ „λ‹¬ν•œλ‹€.

const promise = fetch(url [,options])

fetch ν•¨μˆ˜λŠ” HTTP 응닡을 λ‚˜νƒ€λ‚΄λŠ” Response 객체λ₯Ό λž˜ν•‘ν•œ Promise 객체λ₯Ό λ°˜ν™˜ν•œλ‹€.

fetch('https://jsonplaceholder.typicode.com/todos/1')
  // responseλŠ” HTTP 응닡을 λ‚˜νƒ€λ‚΄λŠ” Response 객체이닀.
  // json λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ Response κ°μ²΄μ—μ„œ HTTP 응닡 λͺΈμ²΄λ₯Ό μ·¨λ“ν•˜μ—¬ μ—­μ§λ ¬ν™”ν•œλ‹€.
  .then(response => response.json())
  // json은 μ—­μ§λ ¬ν™”λœ HTTP 응닡 λͺΈμ²΄μ΄λ‹€.
  .then(json => console.log(json));
  // {userId: 1, id: 1, title: "delectus aut autem", completed: false}

fetch ν•¨μˆ˜λŠ” HTTP 응닡을 λ‚˜νƒ€λ‚΄λŠ” Response 객체λ₯Ό λž˜ν•‘ν•œ ν”„λ‘œλ―ΈμŠ€λ₯Ό λ°˜ν™˜ν•˜λ―€λ‘œ 후속 처리 λ©”μ„œλ“œ then을 톡해 ν”„λ‘œλ―ΈμŠ€κ°€ resolve ν•œ Response 객체λ₯Ό 전달받을 수 μžˆλ‹€.

const wrongUrl = 'https://jsonplaceholder.typicode.com/XXX/1';

// λΆ€μ μ ˆν•œ URL이 μ§€μ •λ˜μ—ˆκΈ° λ•Œλ¬Έμ— 404 Not Found μ—λŸ¬κ°€ λ°œμƒν•œλ‹€.
fetch(wrongUrl)
  .then(() => console.log('ok'))
  .catch(() => console.log('error'));

fetch ν•¨μˆ˜κ°€ λ°˜ν™˜ν•˜λŠ” ν”„λ‘œλ―ΈμŠ€λŠ” 기본적으둜 404 Not Foundλ‚˜ 500 Internal Server Error와 같은 HTTP μ—λŸ¬κ°€ λ°œμƒν•΄λ„ μ—λŸ¬λ₯Ό rejectν•˜μ§€ μ•Šκ³  λΆˆλ¦¬μ–Έ νƒ€μž…μ˜ ok μƒνƒœλ₯Ό false둜 μ„€μ •ν•œ Response 객체λ₯Ό resolveν•œλ‹€. μ˜€ν”„λΌμΈ λ“±μ˜ λ„€νŠΈμ›Œν¬ μž₯μ• λ‚˜ CORS μ—λŸ¬μ— μ˜ν•΄ μš”μ²­μ΄ μ™„λ£Œλ˜μ§€ λͺ»ν•œ κ²½μš°μ—λ§Œ ν”„λ‘œλ―ΈμŠ€λ₯Ό rejectν•œλ‹€. λ”°λΌμ„œ λΆˆλ¦¬μ–Ένƒ€μž…μ˜ ok μƒνƒœλ₯Ό λͺ…μ‹œμ μœΌλ‘œ 확인할 ν•„μš”κ°€ μžˆλ‹€.

const wrongUrl = 'https://jsonplaceholder.typicode.com/XXX/1';

// λΆ€μ μ ˆν•œ URL이 μ§€μ •λ˜μ—ˆκΈ° λ•Œλ¬Έμ— 404 Not Found μ—λŸ¬κ°€ λ°œμƒν•œλ‹€.
fetch(wrongUrl)
  // responseλŠ” HTTP 응닡을 λ‚˜νƒ€λ‚΄λŠ” Response 객체닀.
  .then(response => {
    if (!response.ok) throw new Error(response.statusText);
    return response.json();
  })
  .then(todo => console.log(todo))
  .catch(err => console.error(err));

fetch ν•¨μˆ˜λ₯Ό 톡해 HTTP μš”μ²­μ„ 전솑할 수 μžˆλ‹€.

const request = {
  get(url) {
    return fetch(url);
  },
  post(url, payload) {
    return fetch(url, {
      method: 'POST',
      headers: { 'content-Type': 'application/json' },
      body: JSON.stringify(payload)
    });
  },
  patch(url, payload) {
    return fetch(url, {
      method: 'PATCH',
      headers: { 'content-Type': 'application/json' },
      body: JSON.stringify(payload)
    });
  },
  delete(url) {
    return fetch(url, { method: 'DELETE' });
  }
};
  • GET μš”μ²­
    request.get('https://jsonplaceholder.typicode.com/todos/1')
      .then(response => {
        if (!response.ok) throw new Error(response.statusText);
        return response.json();
      })
      .then(todos => console.log(todos))
      .catch(err => console.error(err));
    // {userId: 1, id: 1, title: "delectus aut autem", completed: false}
  • POST μš”μ²­
    request.post('https://jsonplaceholder.typicode.com/todos', {
      userId: 1,
      title: 'JavaScript',
      completed: false
    }).then(response => {
        if (!response.ok) throw new Error(response.statusText);
        return response.json();
      })
      .then(todos => console.log(todos))
      .catch(err => console.error(err));
    // {userId: 1, title: "JavaScript", completed: false, id: 201}
  • PATCH μš”μ²­
    request.patch('https://jsonplaceholder.typicode.com/todos/1', {
      completed: true
    }).then(response => {
        if (!response.ok) throw new Error(response.statusText);
        return response.json();
      })
      .then(todos => console.log(todos))
      .catch(err => console.error(err));
    // {userId: 1, id: 1, title: "delectus aut autem", completed: true}
  • DELETE μš”μ²­
    request.delete('https://jsonplaceholder.typicode.com/todos/1')
      .then(response => {
        if (!response.ok) throw new Error(response.statusText);
        return response.json();
      })
      .then(todos => console.log(todos))
      .catch(err => console.error(err));
    // {}
profile
μ΄μ‚¬μ€‘μž…λ‹ˆλ‹€!🌟https://velog.io/@devkyoung2

0개의 λŒ“κΈ€

κ΄€λ ¨ μ±„μš© 정보