๐Ÿ“‹ ๋ชจ๋˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ Deep Dive | 45์žฅ ํ”„๋กœ๋ฏธ์Šค

waterglassesยท2022๋…„ 7์›” 21์ผ
0
post-thumbnail

๋ชจ๋˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ Deep Dive ๋„์„œ์˜ 45์žฅ ํ”„๋กœ๋ฏธ์Šค๋ฅผ ์ •๋ฆฌํ•˜์˜€์Šต๋‹ˆ๋‹ค.

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•œ ํ•˜๋‚˜์˜ ํŒจํ„ด์œผ๋กœ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. ํ•˜์ง€๋งŒ ์ „ํ†ต์ ์ธ ์ฝœ๋ฐฑ ํŒจํ„ด์€ ์ฝœ๋ฐฑ ํ—ฌ๋กœ ์ธํ•ด ๊ฐ€๋…์„ฑ์ด ๋‚˜์˜๊ณ  ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ ์ค‘ ๋ฐœ์ƒํ•œ ์—๋Ÿฌ์˜ ์ฒ˜์น˜๊ฐ€ ๊ณค๋ž€ํ•˜๋ฉฐ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๋ฅผ ํ•œ๋ฒˆ์— ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐ๋„ ํ•œ๊ณ„๊ฐ€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ํ”„๋กœ๋ฏธ์Šค๊ฐ€ ๋“ฑ์žฅํ•˜์˜€๋‹ค.

45.1 ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•œ ์ฝœ๋ฐฑ ํŒจํ„ด์˜ ๋‹จ์ 

45.1.1 ์ฝœ๋ฐฑ ํ—ฌ

๋น„๋™๊ธฐ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ํ•จ์ˆ˜ ๋‚ด๋ถ€์˜ ๋น„๋™๊ธฐ๋กœ ๋™์ž‘ํ•˜๋Š” ์ฝ”๋“œ๊ฐ€ ์™„๋ฃŒ๋˜์ง€ ์•Š์•˜๋‹ค ํ•ด๋„ ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š๊ณ  ์ฆ‰์‹œ ์ข…๋ฃŒ๋œ๋‹ค.

let g = 0

setTimeout(() => {
  g = 100
}, 0)
console.log(g) // 0

์œ„์ฒ˜๋Ÿผ ๋น„๋™๊ธฐ ํ•จ์ˆ˜ ๋‚ด๋ถ€์˜ ๋น„๋™๊ธฐ๋กœ ๋™์ž‘ํ•˜๋Š” ์ฝ”๋“œ์—์„œ ์ฒ˜๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ์™ธ๋ถ€๋กœ ๋ฐ˜ํ™˜ํ•˜๊ฑฐ๋‚˜ ์ƒ์œ„ ์Šค์ฝ”ํ”„์˜ ๋ณ€์ˆ˜์— ํ• ๋‹นํ•˜๋ฉด ๊ธฐ๋Œ€ํ•œ ๋Œ€๋กœ ๋™์ž‘ํ•˜์ง€ ์•Š๋Š”๋‹ค.

์ด์ฒ˜๋Ÿผ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ ๊ฒฐ๊ณผ์— ๋Œ€ํ•œ ํ›„์† ์ฒ˜๋ฆฌ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” ๋น„๋™๊ธฐ ํ•จ์ˆ˜๊ฐ€ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๊ฒฐ๊ณผ๋ฅผ ๊ฐ€์ง€๊ณ  ๋˜ ๋‹ค์‹œ ๋น„๋™๊ธฐ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๋ณต์žกํ•ด์ง€๋Š” ํ˜„์ƒ์„ ์ฝœ๋ฐฑ ํ—ฌ์ด๋ผ ํ•œ๋‹ค.

45.1.2 ์—๋Ÿฌ ์ฒ˜๋ฆฌ์˜ ํ•œ๊ณ„

๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•œ ์ฝœ๋ฐฑ ํŒจํ„ด์˜ ๋ฌธ์ œ์  ์ค‘์—์„œ ๊ฐ€์žฅ ์‹ฌ๊ฐํ•œ ๊ฒƒ์€ ์—๋Ÿฌ ์ฒ˜๋ฆฌ๊ฐ€ ๊ณค๋ž€ํ•˜๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

try {
  setTimeout(() => {
    throw new Error('error')
  }, 1000)
} catch (e) {
  // ์—๋Ÿฌ๋ฅผ ์บ์น˜ํ•˜์ง€ ๋ชปํ•œ๋‹ค.
  console.log(error)
}

45.2 ํ”„๋กœ๋ฏธ์Šค์˜ ์ƒ์„ฑ

Promise๋Š” ECMAScript ์‚ฌ์–‘์— ์ •์˜๋œ ํ‘œ์ค€ ๋นŒํŠธ์ธ ๊ฐ์ฒด๋‹ค. Promise ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋Š” ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๋ฅผ ์ˆ˜ํ–‰ํ•  ์ฝœ๋ฐฑํ•จ์ˆ˜๋ฅผ ์ธ์ˆ˜๋กœ ์ „๋‹ฌ๋ฐ›๋Š”๋ฐ ์ด ์ฝœ๋ฐฑํ•จ์ˆ˜๋Š” resolve์™€ reject ํ•จ์ˆ˜๋ฅผ ์ธ์ˆ˜๋กœ ์ „๋‹ฌ๋ฐ›๋Š”๋‹ค.

// ํ”„๋กœ๋ฏธ์Šค ์ƒ์„ฑ
const promise = new Promise((resolve, reject) => {
  // Promise ํ•จ์ˆ˜์˜ ์ฝœ๋ฐฑ ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๋ฅผ ์ˆ˜ํ–‰ํ•œ๋‹ค.
  if(๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ ์„ฑ๊ณต){
    resolve('result')
  } else {
    reject('failure reason')
  }
})

๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๊ฐ€ ์„ฑ๊ณตํ•˜๋ฉด resolve ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๊ฐ€ ์‹คํŒจํ•˜๋ฉด reject ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค.

๋น„๋™๊ธฐ ์ž‘์—…์ด ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋Š” 3๊ฐ€์ง€ ์ƒํƒœ

  • Pending(๋Œ€๊ธฐ ์ƒํƒœ)
  • Fulfilled(์„ฑ๊ณต)
  • Rejected(์‹คํŒจ)

Pending ์ƒํƒœ์—์„œ Fulfilled๋กœ ํ•ด๊ฒฐ์ด ๋˜์—ˆ์„ ๋•Œ๋Š” reslove๊ฐ€ ๋œ ๊ฒƒ์ด๊ณ  Pending์ƒํƒœ์—์„œ Rejected์ƒํƒœ๋กœ ๊ฑฐ๋ถ€ ๋˜์—ˆ์„ ๋•Œ๋Š” reject ๋œ ๊ฒƒ์ด๋‹ค.

Promise

์–ด๋–ค ํ•จ์ˆ˜๊ฐ€ Promise๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค๋Š” ๊ฒƒ์€ ๊ทธ ํ•จ์ˆ˜๋Š” ๋น„๋™๊ธฐ ์ ์œผ๋กœ ๋™์ž‘์„ ํ•˜๊ณ  ๋ฐ˜ํ™˜ํ•œ Promise๊ฐ์ฒด๋ฅผ ์ด์šฉํ•ด์„œ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ์˜ ๊ฒฐ๊ณผ ๊ฐ’์„ then๊ณผ catch๋กœ ์ด์šฉํ•˜๊ฒ ๋‹ค๋Š” ์˜๋ฏธ์ด๋‹ค.

45.3 ํ”„๋กœ๋ฏธ์Šค์˜ ํ›„์† ์ฒ˜๋ฆฌ ๋ฉ”์„œ๋“œ

45.3.1 Promise.prototype.then

then ๋ฉ”์„œ๋“œ๋Š” ๋‘ ๊ฐœ์˜ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ์ธ์ˆ˜๋กœ ์ „๋‹ฌ๋ฐ›๋Š”๋‹ค.

  • ์ฒซ๋ฒˆ์งธ ์ฝœ๋ฐฑ ํ•จ์ˆ˜: ํ”„๋กœ๋ฏธ์Šค๊ฐ€ fulfilled ์ƒํƒœ๊ฐ€ ๋˜๋ฉด ํ˜ธ์ถœ๋˜๊ณ  ํ”„๋กœ๋ฏธ์Šค์˜ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ์ธ์ˆ˜๋กœ ์ „๋‹ฌ๋ฐ›๋Š”๋‹ค.
  • ๋‘๋ฒˆ์งธ ์ฝœ๋ฐฑ ํ•จ์ˆ˜: ํ”„๋กœ๋ฏธ์Šค๊ฐ€ rejected ์ƒํƒœ๊ฐ€ ๋˜๋ฉด ํ˜ธ์ถœ๋˜๊ณ  ํ”„๋กœ๋ฏธ์Šค์˜ ์—๋Ÿฌ๋ฅผ ์ธ์ˆ˜๋กœ ์ „๋‹ฌ๋ฐ›๋Š”๋‹ค.

then๋ฉ”์„œ๋“œ๋Š” ์–ธ์ œ๋‚˜ ํ”„๋กœ๋ฏธ์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

45.3.2 Promise.prototype.catch

catch ๋ฉ”์„œ๋“œ์˜ ์ฝœ๋ฐฑํ•จ์ˆ˜๋Š” ํ”„๋กœ๋ฏธ์Šค๊ฐ€ rejected์ƒํƒœ์ธ ๊ฒฝ์šฐ๋งŒ ํ˜ธ์ถœ๋œ๋‹ค.

45.3.3 Promise.prototype.finally

finally ๋ฉ”์„œ๋“œ์˜ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋Š” ํ”„๋กœ๋ฏธ์Šค์˜ ์„ฑ๊ณต ํ˜น์€ ์‹คํŒจ์™€ ์ƒ๊ด€์—†์ด ๋ฌด์กฐ๊ฑด ํ•œ ๋ฒˆ ํ˜ธ์ถœ๋œ๋‹ค.

45.4 ํ”„๋กœ๋ฏธ์Šค์˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ

  • catch ๋ฉ”์„œ๋“œ๋ฅผ ๋ชจ๋“  then ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•œ ์ดํ›„์— ํ˜ธ์ถœํ•˜๋ฉด ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ์—์„œ ๋ฐœ์ƒํ•œ ์—๋Ÿฌ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ then ๋ฉ”์„œ๋“œ ๋‚ด๋ถ€์—์„œ ๋ฐœ์ƒํ•œ ์—๋Ÿฌ๊นŒ์ง€ ๋ชจ๋‘ ์บ์น˜ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • catch ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋˜ํ•œ ๊ฐ€๋…์„ฑ์ด ์ข‹๊ณ  ๋ช…ํ™•ํ•˜๋‹ค.

45.4 ํ”„๋กœ๋ฏธ์Šค ์ฒด์ด๋‹

then, catch, finally ํ›„์† ์ฒ˜๋ฆฌ ๋ฉ”์„œ๋“œ๋Š” ์–ธ์ œ๋‚˜ ํ”„๋กœ๋ฏธ์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฏ€๋กœ ์—ฐ์†์ ์œผ๋กœ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋ฅผ ํ”„๋กœ๋ฏธ์Šค ์ฒด์ด๋‹์ด๋ผ ํ•œ๋‹ค.

45.6 ํ”„๋กœ๋ฏธ์Šค์˜ ์ •์  ๋ฉ”์„œ๋“œ

45.6.1 Promise.resolve / Promise.reject

๋‘ ๋ฉ”์„œ๋“œ๋Š” ์ด๋ฏธ ์กด์žฌํ•˜๋Š” ๊ฐ’์„ ๋ž˜ํ•‘ํ•˜์—ฌ ํ”„๋กœ๋ฏธ์Šค๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•œ๋‹ค. Promise.resolve ๋ฉ”์„œ๋“œ๋Š” ์ธ์ˆ˜๋กœ ์ „๋‹ฌ๋ฐ›์€ ๊ฐ’์„ resolveํ•˜๋Š” ํ”„๋กœ๋ฏธ์Šค๋ฅผ ์ƒ์„ฑํ•œ๋‹ค. Promise.reject ๋ฉ”์„œ๋“œ๋Š” ์ธ์ˆ˜๋กœ ์ „๋‹ฌ๋ฐ›์€ ๊ฐ’์„ rejectํ•˜๋Š” ํ”„๋กœ๋ฏธ์Šค๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

45.6.2 Promise.all

Promise.all ๋ฉ”์„œ๋“œ๋Š” ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๋ฅผ ๋ชจ๋‘ ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.

Promise.all([๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ ํ•จ์ˆ˜, ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ ํ•จ์ˆ˜])
  .then(console.log)
  .catch(console.error);

Promise.all ๋ฉ”์„œ๋“œ๋Š” ํ”„๋กœ๋ฏธ์Šค๋Š” ์š”์†Œ๋กœ ๊ฐ–๋Š” ๋ฐฐ์—ด ๋“ฑ์˜ ์ดํ„ฐ๋Ÿฌ๋ธ”์„ ์ธ์ˆ˜๋กœ ์ „๋‹ฌ๋ฐ›๋Š”๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ „๋‹ฌ๋ฐ›์€ ๋ชจ๋“  ํ”„๋กœ๋ฏธ์Šค๊ฐ€ ๋ชจ๋‘ fulfilled ์ƒํƒœ๊ฐ€ ๋˜๋ฉด ๋ชจ๋“  ์ฒ˜๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ๋ฐฐ์—ด์— ์ €์žฅํ•ด ์ƒˆ๋กœ์šด ํ”„๋กœ๋ฏธ์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

45.6.3 Promise.race

Promise.race๋Š” Promise.all์ฒ˜๋Ÿผ ๋ชจ๋“  ํ”„๋กœ๋ฏธ์Šค๊ฐ€ fulfilled ์ƒํƒœ๊ฐ€ ๋˜๋Š” ๊ฒƒ์„ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ๊ฐ€์žฅ ๋จผ์ € fulfilled ์ƒํƒœ๊ฐ€ ๋œ ํ”„๋กœ๋ฏธ์Šค์˜ ์ฒ˜๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ resolveํ•˜๋Š” ์ƒˆ๋กœ์šด ํ”„๋กœ๋ฏธ์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

45.6.5 Promise.allSettled

Promise.allSettled ๋ฉ”์„œ๋“œ๋Š” ํ”„๋กœ๋ฏธ์Šค๋ฅผ ์š”์†Œ๋กœ ๊ฐ–๋Š” ๋ฐฐ์—ด ๋“ฑ์˜ ์ดํ„ฐ๋Ÿฌ๋ธ”์„ ์ธ์ˆ˜๋กœ ์ „๋‹ฌ๋ฐ›๋Š”๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ „๋‹ฌ๋ฐ›์€ ํ”„๋กœ๋ฏธ์Šค๊ฐ€ ๋ชจ๋‘ settled์ƒํƒœ(fulfilled || rejected)๊ฐ€ ๋˜๋ฉด ์ฒ˜๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ๋ฐฐ์—ด๋กœ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

45.7 ๋งˆ์ดํฌ๋กœํƒœ์Šคํฌ ํ

ํ”„๋กœ๋ฏธ์Šค์˜ ํ›„์† ์ฒ˜๋ฆฌ ๋ฉ”์„œ๋“œ์˜ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋Š” ํƒœ์Šคํฌ ํ๊ฐ€ ์•„๋‹ˆ๋ผ ๋งˆ์ดํฌ๋กœํƒœ์Šคํฌ ํ์— ์ €์žฅ๋œ๋‹ค.
๋งˆ์ดํฌ๋กœํƒœ์Šคํฌ ํ๋Š” ํƒœ์Šคํฌํ๋ณด๋‹ค ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋†’๋‹ค. ์ฆ‰, ์ด๋ฒคํŠธ ๋ฃจํ”„๋Š” ์ฝœ ์Šคํƒ์ด ๋น„๋ฉด ๋จผ์ € ๋งˆ์ดํฌ๋กœํƒœ์Šคํฌ ํ์—์„œ ๋Œ€๊ธฐํ•˜๊ณ  ์žˆ๋Š” ํ•จ์ˆ˜๋ฅผ ๊ฐ€์ ธ์™€ ์‹คํ–‰ํ•œ๋‹ค. ์ดํ›„ ๋งˆ์ดํฌ๋กœํƒœ์Šคํฌ ํ๊ฐ€ ๋น„๋ฉด ํƒœ์Šคํฌ ํ์—์„œ ๋Œ€๊ธฐํ•˜๊ณ  ์žˆ๋Š” ํ•จ์ˆ˜๋ฅผ ๊ฐ€์ ธ์™€ ์‹คํ–‰ํ•œ๋‹ค.

45.8 fetch

fetch๋Š” XMLHttpRequest์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ HTTP ์š”์ฒญ ์ „์†ก ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋Š” ํด๋ผ์ด์–ธํŠธ ์‚ฌ์ด๋“œ Web API๋‹ค. ํ”„๋กœ๋ฏธ์Šค๋ฅผ ์ง€์›ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•œ ์ฝœ๋ฐฑ ํŒจํ„ด์˜ ๋‹จ์ ์—์„œ ์ž์œ ๋กญ๋‹ค.

fetch ํ•จ์ˆ˜๋Š” HTTP ์‘๋‹ต์„ ๋‚˜ํƒ€๋‚ด๋Š” Response ๊ฐ์ฒด๋ฅผ ๋ž˜ํ•‘ํ•œ Promise ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

fetch(url)
  .then(res => {
  if(!res.ok) throw new Error(res.statusText)
  return res.json()
})

Ref

  • ์ด์›…๋ชจ ์ €, โŒœ๋ชจ๋˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ Deep DiveโŒŸ, ์œ„ํ‚ค๋ถ์Šค
profile
๋งค ์ˆœ๊ฐ„ ์„ฑ์žฅํ•˜๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ๋˜๋ ค๊ณ  ๋…ธ๋ ฅํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

0๊ฐœ์˜ ๋Œ“๊ธ€