JavaScript - The Complete Guide 2022

Section 17: Asynchronous Code - Code That "Takes a Bit Longer"

olivia_yj 2022. 11. 2. 20:08

The goals

๐Ÿ’ช๐ŸปWhat is "Async Code"?

โœŒ๐ŸปWorking with Callbacks

๐Ÿ‘๐ŸปPromises

๐Ÿ‘Š๐Ÿปasync / await

 

quiz

์งˆ๋ฌธ 1:

๋™๊ธฐ ์ฝ”๋“œ์™€ ๋น„๋™๊ธฐ ์ฝ”๋“œ์˜ ์ฐจ์ด๋Š” ๋ฌด์—‡์ผ๊นŒ์š”?

  • ๋™๊ธฐ ์ฝ”๋“œ๋Š” ํ–‰ ๋‹จ์œ„๋กœ ์‹คํ–‰๋˜๊ณ  ๋น„๋™๊ธฐ ์ฝ”๋“œ๋Š” ์ผ๋ถ€ ์ž‘์—…(์˜ˆ: ํƒ€์ด๋จธ)์ด ์™„๋ฃŒ๋˜๋ฉด ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.

  • ๋™๊ธฐ ์ฝ”๋“œ๋Š” ๋น„๋™๊ธฐ ์ฝ”๋“œ(์˜ˆ: ํƒ€์ด๋จธ)๊ฐ€ ๋ฐœ๊ฒฌ๋  ๋•Œ๊นŒ์ง€ ์‹คํ–‰๋˜๊ณ  ์ด ๊ฒฝ์šฐ ํ•ด๋‹น ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰์ด ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ์‹คํ–‰์ด ์ผ์‹œ ์ค‘์ง€๋ฉ๋‹ˆ๋‹ค.

  • ๋‘˜ ์‚ฌ์ด์—๋Š” ์ฐจ์ด๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

์งˆ๋ฌธ 2:

์ด ์ฝ”๋“œ๋Š” ์ฝ˜์†”์— ๋ฌด์—‡์„ ์ถœ๋ ฅํ• ๊นŒ์š”?

console.log('Starting!);
setTimeout(() => {
  console.log('Timer completed!');
}, 10);
console.log('Finished!');
    1. Starting!
    2. Timer completed!
    3. Finished!
    1. Starting!
    2. Finished!
    3. Timer completed!
  • ์ถœ๋ ฅ ์ˆœ์„œ๊ฐ€ ํ•ญ์ƒ ๊ฐ™์€ ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค - CPU์™€ ์—ฌ๋Ÿฌ ๋‹ค๋ฅธ ์š”์ธ์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง‘๋‹ˆ๋‹ค.

์งˆ๋ฌธ 3:

JavaScript๋Š” ๋น„๋™๊ธฐ ์ฝ”๋“œ ์‹คํ–‰์„ ์–ด๋–ป๊ฒŒ ์ฒ˜๋ฆฌํ• ๊นŒ์š”?

  • ๋‹ค์ค‘ ์Šค๋ ˆ๋“œ๋กœ ์ฒ˜๋ฆฌํ•˜๊ณ  ๊ธฐ๋ณธ ์Šคํฌ๋ฆฝํŠธ ์‹คํ–‰์ด ์ฐจ๋‹จ๋˜์ง€ ์•Š๋„๋ก ๋” ์˜ค๋ž˜ ๊ฑธ๋ฆฌ๋Š” ์ž‘์—…(์˜ˆ: ํƒ€์ด๋จธ)์„ ๋ณ„๋„์˜ ์Šค๋ ˆ๋“œ๋กœ ๋„˜๊น๋‹ˆ๋‹ค.

  • ๋‹จ์ผ ์Šค๋ ˆ๋“œ๋กœ ์ฒ˜๋ฆฌํ•˜๊ณ  ๋” ์˜ค๋ž˜ ๊ฑธ๋ฆฌ๋Š” ์ž‘์—…(์˜ˆ: ํƒ€์ด๋จธ)์ด ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ์Šคํฌ๋ฆฝํŠธ ์‹คํ–‰์„ ์ฐจ๋‹จํ•ฉ๋‹ˆ๋‹ค.

  • ๋‹จ์ผ ์Šค๋ ˆ๋“œ์ด์ง€๋งŒ ๋” ์˜ค๋ž˜ ๊ฑธ๋ฆฌ๋Š” ์ž‘์—…(์˜ˆ: ํƒ€์ด๋จธ)์„ (๋‹ค์ค‘ ์Šค๋ ˆ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š”) ๋ธŒ๋ผ์šฐ์ €๋กœ ๋„˜๊น๋‹ˆ๋‹ค.

 

Instead of having multiple levels and that makes our code way more readable.

 

If we put catch in the middle of the promise code, then all prior then would be skipped.

 

ํ”„๋กœ๋ฏธ์Šค ์ƒํƒœ & “finally”

์—ฌ๋Ÿฌ๋ถ„์€ ๋‹ค์–‘ํ•œ ํ”„๋กœ๋ฏธ์Šค ์ƒํƒœ์— ๋Œ€ํ•ด ๋ฐฐ์› ์Šต๋‹ˆ๋‹ค.

  • PENDING => ํ”„๋กœ๋ฏธ์Šค๊ฐ€ ์ž‘๋™ ์ค‘์ด๋ฉฐthen()์ด๋‚˜ catch() ๊ฐ€ ์‹คํ–‰๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค
  • RESOLVED =>  ํ”„๋กœ๋ฏธ์Šค๊ฐ€ ํ•ด๊ฒฐ๋์Šต๋‹ˆ๋‹ค => then()์ด ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค
  • REJECTED  => · ํ”„๋กœ๋ฏธ์Šค๊ฐ€ ๊ฑฐ์ ˆ๋์Šต๋‹ˆ๋‹ค=> catch()์ด ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค

catch()๋‚˜ then() ๋ธ”๋ก ๋‹ค์Œ์— ๋˜ ๋‹ค๋ฅธ then() ๋ธ”๋ก์ด ์žˆ์œผ๋ฉด ํ”„๋กœ๋ฏธ์Šค๊ฐ€ PENDING ๋ชจ๋“œ๋กœ ๋‹ค์‹œ ๋“ค์–ด๊ฐ‘๋‹ˆ๋‹ค. (์ฐธ๊ณ : then()๊ณผ catch()๋Š” ํ•ญ์ƒ ์ƒˆ๋กœ์šด ํ”„๋กœ๋ฏธ์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค - ์–ด๋–ค ๊ฒƒ์œผ๋กœ๋„ ํ•ด๊ฒฐ๋˜์ง€ ์•Š๊ฑฐ๋‚˜then()๋‚ด๋ถ€์—์„œ returnํ•œ ๊ฒƒ์œผ๋กœ ํ•ด๊ฒฐ๋ฉ๋‹ˆ๋‹ค). ๋” ์ด์ƒ then() ๋ธ”๋ก์ด ๋‚จ์•„ ์žˆ์ง€ ์•Š์€ ๊ฒฝ์šฐ์—๋งŒ ์•„๋ž˜์˜ ์ตœ์ข… ๋ชจ๋“œ๋กœ ๋“ค์–ด๊ฐ‘๋‹ˆ๋‹ค. SETTLED.

SETTLED๊ฐ€ ๋˜๋ฉด ํŠน์ˆ˜ ๋ธ”๋ก์ธ finally()๋กœ ์ตœ์ข… ์ •๋ฆฌ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด์ „์— ํ•ด๊ฒฐ๋๋“  ๊ฑฐ๋ถ€๋๋“  ์ƒ๊ด€์—†์ด finally()์—๋Š” ๋„๋‹ฌํ•ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ์€ ์˜ˆ์‹œ์ž…๋‹ˆ๋‹ค:

somePromiseCreatingCode()
  .then(firstResult => {
    return 'done with first promise';
  })
  .catch(err => {
    // would handle any errors thrown before
    // implicitly returns a new promise - just like then()
  })
  .finally(() => {
    // the promise is settled now - finally() will NOT return a new promise!
    // you can do final cleanup work here
  });

finally() ๋ธ”๋ก์€ ์ถ”๊ฐ€ํ•  ํ•„์š” ์—†์Šต๋‹ˆ๋‹ค(๊ฐ•์˜์—์„œ ํ•˜์ง€ ์•Š์•˜์œผ๋‹ˆ๊นŒ์š”).

 

Promise

 

 

Promise.all / Promise.race

 

 

Async / Await

 

 

 

quiz

์งˆ๋ฌธ 1:

JavaScript์—์„œ ํ”„๋กœ๋ฏธ์Šค๋ž€ ๋ฌด์—‡์ผ๊นŒ์š”?

  • ํ”„๋กœ๋ฏธ์Šค๋Š” JavaScript์—์„œ ๋น„๋™๊ธฐ ์ฝ”๋“œ๋ฅผ ์ž‘๋™์‹œํ‚ค๋Š” ์œ ์ผํ•œ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

  • ํ”„๋กœ๋ฏธ์Šค๋Š” ์ž‘์—…์„ ๋” ์‰ฝ๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด (๋น„๋™๊ธฐ) ์ฝ”๋“œ๋ฅผ "๊ฐ์‹ธ๋Š”" ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค.

  • ํ”„๋กœ๋ฏธ์Šค๋Š” Http ์š”์ฒญ์„ ๋ฐฑ์—”๋“œ ์„œ๋ฒ„๋กœ ๋ณด๋‚ด๊ณ  ์‘๋‹ต์œผ๋กœ ์ž‘์—…ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

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

 

์งˆ๋ฌธ 2:

ํ”„๋กœ๋ฏธ์Šค์˜ ๋งฅ๋ฝ์—์„œ “์ฒด์ด๋‹(Chaining)”์ด๋ž€ ๋ฌด์—‡์ผ๊นŒ์š”?

  • ๊ฐ then() ๋ธ”๋ก์ด ์ƒˆ ํ”„๋กœ๋ฏธ์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ(๋ฐ˜ํ™˜ํ•  ํ•„์š”๋Š” ์—†์Œ) ์—ฌ๋Ÿฌ ํ”„๋กœ๋ฏธ์Šค๋ฅผ ์„œ๋กœ ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ์ด๋Š” ํ”„๋กœ๋ฏธ์Šค ๋‚ด์—์„œ ๋‹ค์–‘ํ•œ ๋ฐฐ์—ด ๋ฉ”์„œ๋“œ(filter() ๋“ฑ)๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

  • ๊ฐ then()๊ณผ catch() ๋ฉ”์„œ๋“œ๋Š” ์•„์ง SETTLED ๋˜์–ด์•ผ ํ•˜๋Š” ์ƒˆ๋กœ์šด ํ”„๋กœ๋ฏธ์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ธฐ ๋•Œ๋ฌธ์— then()๊ณผ catch() ๋ฉ”์„œ๋“œ๋ฅผ ์„œ๋กœ์— ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ค๋‹ต์ž…๋‹ˆ๋‹ค. ๋‹ค์‹œ ์‹œ๋„ํ•˜์„ธ์š”.

์™„์ „ํ•˜๊ฒŒ ์˜ณ์€ ๋‹ต์€ ์•„๋‹™๋‹ˆ๋‹ค. then() ๋ธ”๋ก์€ ์•„๋ฌด ๊ฒƒ๋„ ๋ฐ˜ํ™˜ํ•˜์ง€ ์•Š๋”๋ผ๋„ ํ•ญ์ƒ ์ƒˆ๋กœ์šด ํ”„๋กœ๋ฏธ์Šค๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์ฐธ๊ณ ๋กœ catch() ๋ธ”๋ก๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค.

return ๋ฌธ์„ ์ถ”๊ฐ€ํ•˜์ง€ ์•Š๋”๋ผ๋„ then()๊ณผ catch()๋Š” ํ•ญ์ƒ ์ƒˆ๋กœ์šด ํ”„๋กœ๋ฏธ์Šค๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

 

์งˆ๋ฌธ 3:

์•„๋ž˜ ์˜ˆ์—์„œ ๋งˆ์ง€๋ง‰ then() ๋ธ”๋ก์ด ์‹คํ–‰๋ ๊นŒ์š”(์ฆ‰ ์ „๋‹ฌ๋œ ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋ ๊นŒ์š”)?

const myPromise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('Timer completed!');
  }, 1000);
})
  .then((text) => { throw new Error('Failed!') })
  .catch(err => console.log(err))
  .then(() => console.log('Does that execute?'));
  • ๊ทธ๋ ‡์Šต๋‹ˆ๋‹ค!

  • ์•„๋‹ˆ์˜ค, ์ด์ „์— ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

  • ์•„๋‹ˆ์˜ค, ํ”„๋กœ๋ฏธ์Šค ์ฒด์ธ๋‹น ๋‘ ๊ฐœ ์ด์ƒ์˜ then()๊ณผ catch() ๋ธ”๋ก์„ ๊ฐ€์งˆ ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

then()๊ณผ catch() ๋ธ”๋ก์ด ์›ํ•˜๋Š” ๋งŒํผ ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

catch() ๋ธ”๋ก์„ ํ†ตํ•ด ์˜ค๋ฅ˜๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ํ•œ ์ดํ›„์—๋Š” then() ๋ธ”๋ก์ด ์ž‘๋™ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. catch()๋Š” ๋˜ํ•œ ์ƒˆ๋กœ์šด ํ”„๋กœ๋ฏธ์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

 

์งˆ๋ฌธ 4:

async/ await๊ณผ ํ”„๋กœ๋ฏธ์Šค์˜ ์ฐจ์ด์ ์€ ๋ฌด์—‡์ธ๊ฐ€์š”?

  • async/ await๋Š” ๋น„๋™๊ธฐ ์ฝ”๋“œ๋ฅผ ์ฒ˜๋ฆฌ์— ๋Œ€ํ•ด์„œ๋Š” ์™„์ „ํžˆ ๋‹ค๋ฅธ ์ ‘๊ทผ ๋ฐฉ์‹์ด๊ณ  ํ”„๋กœ๋ฏธ์Šค์™€ ์ „ํ˜€ ๊ด€๋ จ์ด ์—†์Šต๋‹ˆ๋‹ค.

  • async/ await๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋น„๋™๊ธฐ ์ฝ”๋“œ๋ฅผ ๋™๊ธฐ ์ฝ”๋“œ๋กœ ์ „ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • async/ await๋Š” ๊ฒฐ๊ตญ ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ์—ฌ์ „ํžˆ ํ”„๋กœ๋ฏธ์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ฝ”๋“œ ๋ณ€ํ™˜์ž…๋‹ˆ๋‹ค.

 

์งˆ๋ฌธ 5:

์•„๋ž˜์˜ ์ฝ”๋“œ์™€ ๋™์ผํ•œ ํ”„๋กœ๋ฏธ์Šค๋Š” ๋ฌด์—‡์ผ๊นŒ์š”?

async function wait() {
  try {
    const result = await doSomething();
    console.log(result);
  } catch (error) {
    console.log('Error!');
  }
}
    1. function wait() {
    2.   doSomething()
    3.     .catch(error => {
    4.       console.log('Error!');
    5.     })
    6.     .then(result => {
    7.       console.log(result);
    8.     });
    9. }
    1. function wait() {
    2.   doSomething()
    3.     .then(result => {
    4.       console.log(result);
    5.     })
    6.     .catch(error => {
    7.       console.log('Error!');
    8.     });
    9. }
    1. function wait() {
    2.   doSomething()
    3.     .then(result => {
    4.        try {
    5.           console.log(result);
    6.        } catch (error) {
    7.           console.log('Error!');
    8.        }
    9.    });
    10. }