JavaScript Promise

Promise

  • promise: ๋น„๋™๊ธฐ๋ฅผ ๊ฐ„ํŽธํ•˜๊ฒŒ ์ฒ˜๋ฆฌ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” object

  • ์ •ํ•ด์ง„ ์žฅ์‹œ๊ฐ„์˜ ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•˜๊ณ  ์„ฑ๊ณตํ•ด์ง„ ๋ฉ”์„ธ์ง€์™€ ํ•จ๊ป˜ ๊ธฐ๋Šฅ ์ˆ˜ํ–‰ ์•„๋‹ˆ๋ฉด ์—๋Ÿฌ๊ฐ€ ๋œธ

Producer

// Promise is a JavaScript object for asynchronous peration
// state (์ƒํƒœ):pending -> fulfilled or rejected 
// producer vs cosumer ๋งŒ๋“œ๋Š”์‚ฌ๋žŒ/ ์†Œ๋น„ํ•˜๋Š”์‚ฌ๋žŒ

const promise = new Promise((resolve, reject) => {
// when new Promise is created, the ececutor runs automatically.
//doing some heavy work (network, read files)
// ์ฝ์–ด์˜ค๋Š”๊ฒƒ, ๋„คํŠธ์›Œํฌ ์ด๋Ÿฐ๊ฒƒ๋“ค์€ ๋ฌด๊ฒ๊ธฐ๋•Œ๋ฌธ์— ๋น„๋™๊ธฐ๋กœ ์ฒ˜๋ฆฌํ•˜๋Š”๊ฒƒ์ด ์ข‹๋‹ค
// promise๊ฐ€ ๋งŒ๋“ค์–ด์ง„ ์ˆœ๊ฐ„ ๋ฐ”๋กœ ์ˆ˜ํ–‰์„ ํ•˜๊ฒŒ๋จ
// ์‚ฌ์šฉ์ž๊ฐ€ ๋ฒ„ํŠผ์„ ๋ˆŒ๋ €์„๋•Œ ๋„คํŠธ์›Œํฌ๊ฐ€ ์ž‘๋™๋˜๊ฒŒ ํ•˜๋Š”๊ฒƒ์€ ๋ฐ”๋กœ ์ˆ˜ํ–‰๋˜๊ธฐ๋•Œ๋ฌธ์— ๋งž์ง€์•Š์Œ 
    console.log('doing something...');
    setTimeout(() => {
       resolve('ellie')
     //reject(new Error('no network'));
    }, 2000);
});

consumers : then, catch, finally

// ์•ฝ์†๋œ ๊ฐ’์„ ์ž˜ ๋ฐ›์•„์˜จ๋‹ค๋ฉด ์ „๋‹ฌ๋˜์„œ ๊ฒฐ๊ณผ๋ฌผ์„ ์ถœ๋ ฅ์‹œํ‚ด 
// value์˜ ๊ฐ’์€ ์œ„์— ์ฒ˜๋ฆฌ๊ณผ์ •์ด ์ž˜ ์ง„ํ–‰๋˜ ellie๋ผ๊ณ  ์ฒ˜๋ฆฌ๋œ ๊ฐ’์ด ๋“ค์–ด์˜ค๊ฒŒ ๋จ
//than์€ promise๋กœ ๋ฆฌํ„ด๋˜๊ณ  ๋‹ค์‹œ catch ๋ฅผ ๋ถ™์ด๊ฒŒ ๋œ๋‹ค.
    promise.then((value) => {
    console.log(value);
    })
    .catch(error => {
        console.log(error);
    })
   .finally(() => {
       console.log('finally'); //์„ฑ๊ณตํ•˜๋˜ ์‹คํŒจํ•˜๋˜ ์ƒ๊ด€์—†์ด ์–ด๋–ค๊ธฐ๋Šฅ์„ ๋งˆ์ง€๋ง‰์œผ๋กœ ์ˆ˜ํ–‰ํ•˜๊ณ  ์‹ถ์„๋•Œ finally๋ฅผ ์‚ฌ์šฉํ•จ
   });

promise chaining

const fetchNumber = new Promise((resolve, reject) => {
    setTimeout(() => resolve(1), 1000); // Promise ๋Š” 1์ดˆ ์žˆ๋‹ค๊ฐ€ ์ˆซ์ž 1์„ ์ „๋‹ฌ
});
fetchNumber
    .then(num => num * 2) // 2
    .then(num => num * 3) //6
    .then(num => {
        return new Promise((resolve, reject) => { // ์ƒˆ๋กœ์šด Promise๋ฅผ ๋ฆฌํ„ด
        setTimeout(() => resolve(num - 1), 1000); //5
        });
    })
    .then(num => console.log(num)); //5

Error Handling

// ์•”๋‹ญ์„ ๋ฐ›์•„์˜ค๋Š” 
const getHen = () =>
    new Promise((resolve, reject) => {
        setTimeout(() => resolve('๐Ÿ”'), 1000);
    });
// ์•”๋‹ญ์„ ๋ฐ›์•„์„œ ๋‹ญ์œผ๋กœ๋ถ€ํ„ฐ ๋‹ฌ๊ฑ€์„ ์–ป์–ด์˜ค๋Š” 
const getEgg = hen =>
    new Promise((resolve, reject) => {
        setTimeout(() => reject(new Error(`ERROR! ${hen} => ๐Ÿฅš`)), 1000);
    });
// ๋‹ฌ๊ฑ€์„ ๋ฐ›์•„์™€์„œ ์š”๋ฆฌํ•˜๋Š”๊ฒƒ 
const cook = egg =>
    new Promise((resolve, reject) => {
        setTimeout(() => resolve(`${egg} => ๐Ÿณ`), 1000);
    }); 

// ๊ณ„๋ž€์„ ๋ฐ›์•„์˜ค๋Š”๊ฒƒ์— ๋ฌธ์ œ๊ฐ€ ์ƒ๊ฒจ๋„ ๋‹ค๋ฅธ๊ฒƒ์œผ๋กœ ๋Œ€์ฒดํ•˜๋Š”๊ฒƒ 
// ํ•ด๋‹น๋ถ€๋ถ„์—์„œ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธดํ›„์—๋„ catch๋ฅผ ์ด์šฉํ•ด error๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ณ  ๊ธฐ๋Šฅ์„ ์ง„ํ–‰ ํ•  ์ˆ˜ ์žˆ๋‹ค. 
getHen() 
    .then(getEgg)
    .catch(error => { // ์—๋Ÿฌ ํ•ธ๋“ค๋ง ๊ณ„๋ž€์„ ๋ฐ›์„๋•Œ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธด๋‹ค๋ฉด -> ๋‹ค๋ฅธ๊ฒƒ์„ ๋ฆฌํ„ดํ•ด์คŒ
        return '๐Ÿฅ—';
    })
    .then(cook)
    .then(console.log)
    .catch(console.log); // ์œ„์˜ ํ•ธ๋“ค๋ง์ด ์—†์œผ๋ฉด ์—๋Ÿฌ ๋ฉ”์„ธ์ง€(ERROR! ๐Ÿ” => ๐Ÿฅš)๊ฐ€ ๋œธ 

์ฝœ๋ฐฑ์ง€์˜ฅ ์ฝ”๋“œ์ˆ˜์ •

class UserStorage {
    loginUser(id, password){
        return new Promise((resolve, reject) => 
             setTimeout(() => {
                if (
                    (id === 'ellie' && password === 'dream') ||
                    (id === 'coder' && password === 'academy')
                ) {
                   resolve(id);
                } else{
                   reject(new Error('not found')); // ์—๋Ÿฌ 'not found'
                }
             }, 2000);
        });

    // ์‚ฌ์šฉ์ž๊ฐ€ ์—˜๋ฆฌ์ด๋ฉด ์ด๋ฆ„์€ ์—˜๋ฆฌ๊ณ  role ์€ ์–ด๋“œ๋ฏผ์ธ ๊ฐ’์„ ์ „๋‹ฌํ•ด์ฃผ๊ณ  ์•„๋‹ˆ๋ฉด not access๋ผ๊ณ  ์ „๋‹ฌ 
 
    getRoles(user) {
      return new Promise((resolve, reject) => {
          if (user === 'ellie') {
               resolve({ name: 'ellie', role: 'admin' });
            } else {
               reject(new Error('no access')); // ์—๋Ÿฌ 'not access'
            }
        }, 1000);
    });
  }
}
// ๋ณ€์ˆ˜๋Š” ๋ณดํ†ต ์†Œ๋ฌธ์ž๋กœ ์‹œ์ž‘ํ•œ๋‹ค ๋™์ผํ•œ์ด๋ฆ„์œผ๋กœ ๋ณ€์ˆ˜ ์„ ์–ธํ•˜์ง€ ๋ง๊ฒƒ 
const userStorage = new UserStorage();
const id = prompt('enter your id'); // ์•„์ด๋”” ๋ฐ›์•„์˜ค๊ธฐ 
const password = prompt('enter your password');
userStorage
.loginUser(id, password) 
.then(userStorage.getRoles) 
.then(user => alert(`hello ${userWithRole.name}, you have a ${userWithRole.role} role`));
.catch(console.log);       

Last updated