๐ŸŽ‰ Javascript Promise object

์ „์ฃผ์€ยท2022๋…„ 11์›” 15์ผ
1

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ

๋ชฉ๋ก ๋ณด๊ธฐ
3/5
post-thumbnail

Promise ๊ฐ์ฒด ๐Ÿฅ

โœ” ๋“ค์–ด๊ฐ€๋ฉด์„œ..

Promise๋Š” ์ฃผ๋กœ ์„œ๋ฒ„์—์„œ ๋ฐ›์•„์˜จ ๋ฐ์ดํ„ฐ๋ฅผ ํ™”๋ฉด์— ํ‘œ์‹œํ•  ๋•Œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœ์ž๊ฐ€ ์„œ๋ฒ„์˜ API url์„ ํ˜ธ์ถœํ•ด์„œ ๊ฒฐ๊ณผ๋ฅผ ํ™”๋ฉด์— ๊ตฌํ˜„ํ•ด์•ผ ํ•  ๋•Œ ํ•„์ˆ˜์ ์ด๊ธฐ ๋•Œ๋ฌธ์— ์ •ํ™•ํ•˜๊ฒŒ ์ดํ•ดํ•˜๊ณ  ์“ฐ๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค.
API๊ฐ€ ์‹คํ–‰๋˜์–ด ์„œ๋ฒ„ ๋ฐ์ดํ„ฐ๋ฅผ ์š”์ฒญ์„ ๋ณด๋‚ผ๋•Œ, ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์˜ค๊ธฐ๋„ ์ „์— ํ™”๋ฉด์— ๋ฐ์ดํ„ฐ๋ฅผ ํ‘œ์‹œํ•˜๋ ค๊ณ  ํ•˜๋ฉด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๊ฑฐ๋‚˜ ๋นˆ ํ™”๋ฉด์ด ๋œน๋‹ˆ๋‹ค. ์ด์™€ ๊ฐ™์€ ๋ฌธ์ œ์ ์„ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ๋ฐฉ๋ฒ• ์ค‘ ํ•˜๋‚˜๊ฐ€ ๋น„๋™๊ธฐ ํ†ต์‹ ์œผ๋กœ ๊ฒฐ๊ณผ์— ๋Œ€ํ•œ ์‘๋‹ต์„ ํ•ด์ฃผ๋Š” ๊ฐ์ฒด ํ”„๋กœ๋ฏธ์Šค์ž…๋‹ˆ๋‹ค.

โœ” Promise ์ •์˜

MDN์— ๋‚˜์˜จ promise์ •์˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

The Promise object represents the eventual completion (or failure) of an asynchronous operation and its resulting value

๊ทธ๋Œ€๋กœ ํ•ด์„์„ ํ•ด๋ณด์ž๋ฉด "promise ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ์— ์‚ฌ์šฉ๋˜๋Š” ๊ฐ์ฒด๋กœ, ์ž‘์—…์˜ ์ตœ์ข… ์™„๋ฃŒ(๋˜๋Š” ์‹คํŒจ)์™€ ๊ทธ ๊ฒฐ๊ณผ ๊ฐ’์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. " ์ž…๋‹ˆ๋‹ค.

ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ ๋น„๋™๊ธฐ(Asynchronous)๋ž€ ์š”์ฒญ๊ณผ ๊ฒฐ๊ณผ๊ฐ€ ๋™์‹œ์— ์ผ์–ด๋‚˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.
์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๋ž€ ํŠน์ • ์ฝ”๋“œ์˜ ์—ฐ์‚ฐ์ด ๋๋‚  ๋•Œ๊นŒ์ง€ ์ฝ”๋“œ์˜ ์‹คํ–‰์„ ๋ฉˆ์ถ”์ง€ ์•Š๊ณ  ๋‹ค์Œ ์ฝ”๋“œ๋ฅผ ๋จผ์ € ์‹คํ–‰ํ•˜๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ํŠน์„ฑ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

promise๋Š” ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๋ฅผ ๋งˆ์น˜ ๋™๊ธฐํ™” ํ•œ๊ฒƒ์ฒ˜๋Ÿผ ์ˆœ์„œ๋Œ€๋กœ ์‹คํ–‰ํ•˜๊ธธ ์›ํ•  ๋•Œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

โœ” Promise ๊ธฐ๋ณธ ๋ฌธ๋ฒ•

Promise์˜ ๊ธฐ๋ณธ๋ฌธ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค!

function ํ•จ์ˆ˜์ด๋ฆ„(๋งค๊ฐœ๋ณ€์ˆ˜){
 	return new Promise((resolve, reject) => {
 	์„ฑ๊ณตํ• ๋•Œ ์‹คํ–‰ํ•  ๋ฌธ์žฅ(resolve)
  	์‹คํŒจํ• ๋•Œ ์‹คํ–‰ํ•  ๋ฌธ์žฅ(reject)
 	}
}

ํ”„๋กœ๋ฏธ์Šค๋ฅผ ๋ฆฌํ„ด๋ฐ›์€ ๊ฐ์ฒด
    .then(์ •์ƒ์ ์œผ๋กœ ํ”„๋กœ๋ฏธ์Šค ๊ฐ์ฒด๊ฐ€ ๋ฆฌํ„ด ๋˜์—ˆ๋‹ค๋ฉด ํ•„์š”ํ•œ ์ผ์„ ์ˆ˜ํ–‰)
    .catch(์—๋Ÿฌ๊ฐ์ฒด๊ฐ€ ๋ฆฌํ„ด๋˜์—ˆ๋‹ค๋ฉด ์—๋Ÿฌ๋ฅผ ์ฒ˜๋ฆฌ)
    .finally(์ตœ์ข…์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•  ์ผ์„ ์ˆ˜ํ–‰)

โ— resolve, reject๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜๋ผ์„œ ๋งˆ์Œ๋Œ€๋กœ ์ด๋ฆ„์„ ์„ค์ •ํ•ด๋„ ๋˜์ง€๋งŒ, ์•ž์€ ์„ฑ๊ณต ๋’ค๋Š” ์‹คํŒจ๋กœ ์ˆœ์„œ๋ฅผ ์ง€์ผœ์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค!
โ— ;๋ฅผ .then().catch().fainally() ์ด ์‚ฌ์ด์— ์ง‘์–ด ๋„ฃ์ง€ ์•Š๋„๋ก ์ฃผ์˜ํ•ฉ๋‹ˆ๋‹ค!

โœ” Promise ๊ธฐ๋ณธ ์˜ˆ์ œ

์ •์˜๋งŒ ๋ณด๋ฉด ์ดํ•ด๊ฐ€ ์–ด๋ ค์šฐ๋‹ˆ, ์•„๋ž˜ ์˜ˆ์ œ์ฝ”๋“œ๋ฅผ ํ†ตํ•ด ์ ์šฉ ํ•ด๋ด…์‹œ๋‹ค.
์ฃผ์–ด์ง„ ์‹œ๊ฐ„์ด ์ง€๋‚˜๋ฉด ์ถœ๋ ฅ๋˜๋Š” ํ”„๋กœ๊ทธ๋žจ์ž…๋‹ˆ๋‹ค.

function runInDelay(seconds){
    return new Promise((resolve, reject) => {
        if(!seconds || seconds < 0){
            reject(new Error('second๊ฐ€ 0๋ณด๋‹ค ์ž‘์Œ!'));
        }
        setTimeout(resolve, seconds*1000);
    }) 
}

runInDelay(2)
    .then(() => console.log('ํƒ€์ด๋จธ๊ฐ€ ์™„๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค'))//promise ๊ฐ์ฒด๊ฐ€ resolve(์„ฑ๊ณต)
    .catch(console.log(error))    //promise ๊ฐ์ฒด๊ฐ€ reject(์‹คํŒจ) ๊ฐ€์ ธ์˜ฌ๋•Œ
    .finally(()=>console.log('๋ชจ๋“  ์ž‘์—…์ด ๋๋‚ฌ์Šต๋‹ˆ๋‹ค.'))  //finally๋Š” ์ตœ์ข…์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•  ์ผ์„ ์ˆ˜ํ–‰
    
console์ฐฝ(2์ดˆ delayํ›„)
    ํƒ€์ด๋จธ๊ฐ€ ์™„๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค
    ๋ชจ๋“  ์ž‘์—…์ด ๋๋‚ฌ์Šต๋‹ˆ๋‹ค.

runInDelay(2) ์‹คํ–‰ ํ›„ resolve -> .then => .finallt ์ˆœ์„œ๋กœ ์‹คํ–‰๋˜๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๋งŒ์•ฝ runInDelay(2)์„ => runInDelay()๋กœ ๋ฐ”๊พธ๊ฒŒ ๋˜๋ฉด ์–ด๋–ค๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ฌ๊นŒ์š”?

console์ฐฝ
	Error: second๊ฐ€ 0๋ณด๋‹ค ์ž‘์Œ!
    at D:\joo\JavaScript\Day8\1_promise1.js:5:20
    at new Promise (<anonymous>)
    at runInDelay (D:\joo\JavaScript\Day8\1_promise1.js:3:12)
    at Object.<anonymous> (D:\joo\JavaScript\Day8\1_promise1.js:13:1)
    at Module._compile (node:internal/modules/cjs/loader:1159:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1213:10)
    at Module.load (node:internal/modules/cjs/loader:1037:32)
    at Module._load (node:internal/modules/cjs/loader:878:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
    at node:internal/main/run_main_module:23:47
	๋ชจ๋“  ์ž‘์—…์ด ๋๋‚ฌ์Šต๋‹ˆ๋‹ค.

if์˜ ์กฐ๊ฑด๋ฌธ์ด true๊ฐ€ ๋˜๋ฉด์„œ, reject -> .catch๋ฌธ -> .finally๋ฌธ์„ ํ†ตํ•ด ํ”„๋กœ๊ทธ๋žจ์ด ์ข…๋ฃŒ๋ฉ๋‹ˆ๋‹ค.


โœ” Promise์˜ 3๊ฐ€์ง€ ์ƒํƒœ (Promise States)

ํ”„๋กœ๋ฏธ์Šค๋Š” 3๊ฐ€์ง€์˜ ์ƒํƒœ๊ฐ€ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.
1. Pending:
- ๋Œ€๊ธฐ์ƒํƒœ๋กœ, fulfilled ๋˜๋Š” rejected ์ƒํƒœ๋กœ ์ „ํ™˜ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
- promise๋ฅผ ์ •์˜ํ•˜๋ฉด์„œ ์ƒ๊น๋‹ˆ๋‹ค.
2. fulfilled:
- ์ดํ–‰์ƒํƒœ๋กœ, ๋ฐ”๋€Œ์ง€ ์•Š๋Š” value์„ ๊ฐ–๊ฒŒ๋˜๊ณ , ์ƒํƒœ๋ฅผ ์ „ํ™˜์„ ํ•ด์„œ๋Š” ์•ˆ๋ฉ๋‹ˆ๋‹ค.
- .then์„ ํ†ตํ•ด ๋ฆฌํ„ด๊ฐ’์„ ๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
3. rejected:
- ์‹คํŒจ์ƒํƒœ๋กœ, ๋ฐ”๋€Œ์ง€ ์•Š๋Š” reason์„ ๊ฐ–๊ฒŒ๋˜๊ณ , ์ƒํƒœ๋ฅผ ์ „ํ™˜์„ ํ•ด์„œ๋Š” ์•ˆ๋ฉ๋‹ˆ๋‹ค.
- .catch๋ฅผ ํ†ตํ•ด ์‹คํŒจํ•œ ์ด์œ ๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

โœ” Promise Chaining

  • ์—ฌ๋Ÿฌ ๊ฐœ์˜ ํ”„๋กœ๋ฏธ์Šค๋ฅผ ์—ฐ๊ฒฐํ•˜์—ฌ ์‚ฌ์šฉ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • promise.reject(): ์ง€์ •๋œ ์ด์œ ๋กœ ๊ฑฐ๋ถ€๋œ ์ƒˆ Promise ๊ฐ์ฒด๋ฅผ ๋ฆฌํ„ดํ•ฉ๋‹ˆ๋‹ค.

  • promise.resolve(): ์ง€์ •๋œ ๊ฐ’์œผ๋กœ ํ™•์ธ๋œ ์ƒˆ Promise ๊ฐ์ฒด๋ฅผ ๋ฆฌํ„ดํ•ฉ๋‹ˆ๋‹ค. .then() ์ด ์žˆ์„๋•Œ ๊ทธ ๋‹ค์Œ promise ๊ฐ์ฒด๋ฅผ ๋ฆฌํ„ดํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

    ์˜ˆ์ œ์ฝ”๋“œ๋ฅผ ํ†ตํ•ด ํ•œ๋ฒˆ ์ดํ•ดํ•ด๋ด…์‹œ๋‹ค!
    ๐Ÿ” => ๐Ÿ“ => ๐Ÿฅš => ๐Ÿณ์„ ์ˆœ์„œ๋Œ€๋กœ ๋ฆฌํ„ดํ•˜๋ฉฐ ์ถœ๋ ฅํ•˜๋Š” ์˜ˆ์ œ์ž…๋‹ˆ๋‹ค.

    function fetchEgg(chicken){return Promise.resolve(`${chicken} => ๐Ÿฅš`); }
    function fryEgg(egg){return Promise.resolve(`${egg} => ๐Ÿณ`);}   
    function getChicken(){return Promise.resolve(`๐Ÿ” => ๐Ÿ“`);}
    
    getChicken()
      .then((chicken) => {return fetchEgg(chicken)})
      .then((egg) => fryEgg(egg)) 
      .then((friedEgg)=>console.log(friedEgg))
      .catch((error) => console.log(error.name));
    
    //----------------------
    //cosole์ฐฝ
    //๐Ÿ” => ๐Ÿ“ => ๐Ÿฅš => ๐Ÿณ
    		```
    
    
  • ๋ชจ๋‘ promise.resolve์ด๋ฏ€๋กœ .then์— ๋”ฐ๋ผ๊ฐ€๋ฉด์„œ ๋ฆฌํ„ด๊ฐ’์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
    ๊ฐ€์žฅ ๋จผ์ € getChicken()์ด ์‹คํ–‰๋˜๊ณ , ๋ฆฌํ„ด๊ฐ’ ๐Ÿ” => ๐Ÿ“๋Š” ๋‹ค์‹œ chicken์•ˆ์— ๋“ค์–ด๊ฐ€ ๊ทธ ๋‹ค์Œ๋ฌธ์žฅ fetchEgg()๊ฐ€ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ๋‹ค์‹œ ๐Ÿ” => ๐Ÿ“ => ๐Ÿฅš๋Š” egg์— ๋“ค์–ด๊ฐ€ fryEgg()๊ฐ€ ์‹คํ–‰๋˜๊ณ  ์ตœ์ข…์ ์œผ๋กœ ๐Ÿ” => ๐Ÿ“ => ๐Ÿฅš => ๐Ÿณ๊ฐ€ ์ถœ๋ ฅ๋˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
  • ๋งŒ์•ฝ์— .reject๊ฐ€ ์žˆ๋‹ค๋ฉด ์–ด๋–ค์‹์œผ๋กœ ์›€์ง์ด๊ฒŒ ๋ ๊นŒ์š”?
    function fetchEgg(chicken){return Promise.resolve(`${chicken} => ๐Ÿฅš`); }
    function fryEgg(egg){return Promise.resolve(`${egg} => ๐Ÿณ`);}  
    function getChicken(){ return Promise.reject(new Error(`์น˜ํ‚จ์ด ๋‹ค ๋–จ์–ด์กŒ์Œ!`));}
    
    getChicken()
      .then((chicken) => {return fetchEgg(chicken)})
      .then((egg) => fryEgg(egg)) 
      .then((friedEgg)=>console.log(friedEgg))
      .catch((error) => console.log(error.name));
    //----------------------
    //cosole์ฐฝ
    //Error
  • ๊ฐ€์žฅ๋จผ์ € getChicken์ด ์‹คํ–‰๋˜์ง€๋งŒ, reject๊ฐ€ ๋œ ํ›„ .catch()๋กœ ๊ฐ€ Error์„ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.
  • ๋งŒ์•ฝ์—, .catch()๊ฐ€ ์•ž์— ์žˆ์—ˆ๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ์š”?
    function fetchEgg(chicken){return Promise.resolve(`${chicken} => ๐Ÿฅš`); }
    function fryEgg(egg){return Promise.resolve(`${egg} => ๐Ÿณ`);}  
    function getChicken(){ return Promise.reject(new Error(`์น˜ํ‚จ์ด ๋‹ค ๋–จ์–ด์กŒ์Œ!`));}
    etChicken()
      .catch((error) => console.log(error.name));
      .then((chicken) => {return fetchEgg(chicken)})
      .then((egg) => fryEgg(egg)) 
      .then((friedEgg)=>console.log(friedEgg))
    //----------------------
    //cosole์ฐฝ
    //Error
    //undefined => ๐Ÿฅš => ๐Ÿณ
  • ๋งจ์•ž์œผ๋กœ ์˜ฎ๊ฒจ์ฃผ๋ฉด ์—๋Ÿฌ์ฒ˜๋ฆฌ๋ฅผ ํ•˜๊ณ ๋‚˜์„œ ๋’ท ๋‚ด์šฉ์„ ์ง„ํ–‰ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ, reject๊ฐ€ ๋œ ํ›„ Error๋ฅผ ์ถœ๋ ฅํ•˜๊ณ , ์•„๋ฌด๊ฒƒ๋„ ๋ฐ˜ํ™˜ํ•˜์ง€ ์•Š์•„ undefined๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ .catch(() => '๐Ÿฅ')์„ ํ–ˆ๋‹ค๋ฉด ๐Ÿฅ์„ ๋ฐ˜ํ™˜ํ•˜์—ฌ ๐Ÿฅ => ๐Ÿฅš => ๐Ÿณ์ด๋ผ๊ณ  ์ถœ๋ ฅ๋˜๊ฒŒ๋ฉ๋‹ˆ๋‹ค.
  • ์œ„์˜ ์‹คํ–‰๋ฌธ์„ ์ถ•์•ฝํ˜•์œผ๋กœ ๊ฐ„๋‹จํ•˜๊ฒŒ ํ‘œํ˜„๊ฐ€๋Šฅ ํ•ฉ๋‹ˆ๋‹ค. ํ•œ์ค„๋งŒ ์ ๊ฒŒ ๋˜๋ฉด ๊ทธ ๊ฐ’์„ returnํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค!
    getChicken()
      .catch(() => '๐Ÿฅ')  //   
      .then(fetchEgg)
      .then(fryEgg) 
      .then(console.log)

    โœ” Promise์˜ ๋น„๋™๊ธฐ

  • ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๊ฐ€ ์–ด๋–ค๋ฐฉ์‹์œผ๋กœ ์ด๋ฃจ์–ด์ง€๋Š”์ง€ ์•Œ์•„๋ณผ๊นŒ์š”? ๋‹ค์Œ ์„ธ๊ฐ€์ง€ ํ•จ์ˆ˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.
    function getBanana(){
      return new Promise((resolve) => {
          setTimeout(()=>{
              resolve('๐ŸŒ');
          },1000);
      })
    }
    function getApple(){
      return new Promise((resolve) => {
          setTimeout(()=>{
              resolve('๐ŸŽ');
          },3000);
      })
    }
    function getOrange(){
      return Promise.reject(new Error(`์˜ค๋ Œ์ง€๋Š” ์—†์Œ`))
    }

์ถœ์ฒ˜
MDN
promise-for-beginner
๋ฅ˜์ •์› ๊ฐ•์‚ฌ๋‹˜ ๊ฐ•์˜์ž๋ฃŒ

profile
๋” ๋ฉ€๋ฆฌ ๋ณด๋„๋ก ํ•ด์š”. ์ง„์ฃผ๋Š” ํ•˜๋ฃจ์•„์นจ์— ์ƒ๊ฒจ๋‚˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

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

comment-user-thumbnail
2022๋…„ 11์›” 17์ผ

๋‹ญ์ด ๋ถˆ์Œํ•ด์š”..

๋‹ต๊ธ€ ๋‹ฌ๊ธฐ