Promise

uoayopยท2021๋…„ 2์›” 27์ผ
0

JavaScript

๋ชฉ๋ก ๋ณด๊ธฐ
13/24
post-thumbnail

Javascript

Promise

๐Ÿ”ง JS์—์„œ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ–ˆ์„ ๋•Œ ๊ทธ ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰ ๋˜๋Š” ๋™์•ˆ, ํ•จ์ˆ˜ ๋ฐ–์˜ ๋‹ค๋ฅธ ์ฝ”๋“œ๋„ ํ•จ๊ป˜ ์‹คํ–‰์ด ๋˜์–ด์•ผํ•œ๋‹ค.

  • Promise๋Š” ์ด๋Ÿฐ ๋น„๋™๊ธฐ์ ์ธ ์ž‘์—…์ด ์ž˜ ์ฒ˜๋ฆฌ๋˜๋„๋ก ํ•ด์ค€๋‹ค.
  • Promise ๊ฐ์ฒด๋Š” ES6์—์„œ ๋“ฑ์žฅํ–ˆ๋‹ค.
console.log(Promise);
//[Function: Promise]

์žฅ์ ๐Ÿ‘๐Ÿป

  • ๋น„๋™๊ธฐ ์ž‘์—…์ด ๋งŽ์•„์ ธ๋„ ์ฝ”๋“œ์˜ ๊นŠ์ด๊ฐ€ ๊นŠ์–ด์ง€์ง€ ์•Š๋Š”๋‹ค.

๋‹จ์ ๐Ÿ‘Ž๐Ÿป

  • ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ ์–ด๋””์„œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋Š”์ง€ ์•Œ ์ˆ˜ ์—†๋‹ค.
  • ํŠน์ • ์กฐ๊ฑด์— ๋”ฐ๋ผ ๋ถ„๊ธฐ๋ฅผ ๋‚˜๋ˆ„๋Š” ์ž‘์—…์ด ์–ด๋ ต๋‹ค.
    โžฃ async-await์œผ๋กœ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Œ

1. ์ƒ์„ฑ์ž๋กœ ํ”„๋กœ๋ฏธ์Šค ๊ฐ์ฒด ๋งŒ๋“ค๊ธฐ

  • ์ƒ์„ฑ์ž์˜ ์ธ์ž๋กœ executor๋ผ๋Š” ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•œ๋‹ค.
new Promise(/* executor ํ•จ์ˆ˜๊ฐ€ ๋“ค์–ด์˜ฌ ์ž๋ฆฌ */);

new Promise(/* executor */ (resolve,reject) => {});

๐Ÿ”ง executor ํ•จ์ˆ˜๋Š” resolve์™€ reject๋ฅผ ์ธ์ž๋กœ ๊ฐ€์ง„๋‹ค.

  • (resove, reject) => { ... }
  • resolve์™€ reject๋Š” ํ•จ์ˆ˜๋‹ค.

๐Ÿค“ ๋Œ€๊ธฐ, ์ดํ–‰, ๊ฑฐ๋ถ€ ์ƒํƒœ

๐Ÿ”ง ์ƒ์„ฑ์ž๋ฅผ ํ†ตํ•ด์„œ ํ”„๋กœ๋ฏธ์Šค ๊ฐ์ฒด๋ฅผ ๋งŒ๋“œ๋Š” ์ˆœ๊ฐ„ pending( ๋Œ€๊ธฐ ) ์ƒํƒœ์— ๋น ์ง„๋‹ค.

๐Ÿ”ง executor ํ•จ์ˆ˜ ์ธ์ž์ธ resolve ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•˜๋ฉด, fulfilled ( ์ดํ–‰ ) ์ƒํƒœ๊ฐ€ ๋œ๋‹ค.

๐Ÿ”ง reject ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•˜๋ฉด , rejected ( ๊ฑฐ๋ถ€ ) ์ƒํƒœ๊ฐ€ ๋œ๋‹ค.

image
(์ด๋ฏธ์ง€ ์ถœ์ฒ˜ : ํŒจ์ŠคํŠธ์บ ํผ์Šค Javascript ์ด์›…์žฌ ๊ฐ•์‚ฌ๋‹˜)

๋น„๋™๊ธฐ ์ƒํ™ฉ์ด ์ผ์–ด๋‚˜๊ธฐ ์ „๊นŒ์ง„ pending ์ƒํƒœ์— ์žˆ๊ณ , ๊ทธ ์ƒํ™ฉ์ด ์ž˜ ์ดํ–‰๋˜๋ฉด resolve() ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  ์ดํ–‰๋˜์ง€ ์•Š์œผ๋ฉด reject() ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋œ๋‹ค.

const p = new Promise((resolve,reject) => {
    /* pending ์ƒํƒœ */
    setTimeout(()=>{
        resolve(); /* fullfilled ์ƒํƒœ */
    },1000);    // 1์ดˆ ํ›„์— resolve ํ˜ธ์ถœ
})

// resolve ๊ฐ€ ํ˜ธ์ถœ๋˜๋ฉด then ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰์ด ๋œ๋‹ค.
p.then(()=>{
    // callback
  	console.log('1000ms ํ›„์— fullfilled ๋ฉ๋‹ˆ๋‹ค.');
  	
  //์ถœ๋ ฅ: '1000ms ํ›„์— fullfilled ๋ฉ๋‹ˆ๋‹ค.'
})

  • ์‹ค๋ฌด์—์„œ๋Š” ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•  ๊ณณ์—์„œ ๋งŒ๋“ค์–ด์„œ ์‚ฌ์šฉํ•œ ๋’ค, then ๊ณผ ์—ฎ์–ด์ค€๋‹ค.
  • ๋Œ€๊ทœ๋ชจ ์ž‘์—…์„ ํ•  ๋•Œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ํ•ด์ค˜์•ผ ํ•œ๋‹ค.
//then ์„ ์„ค์ •ํ•˜๋Š” ์‹œ์ ์„ ์ •ํ™•ํžˆ ํ•˜๊ณ , ํ•จ์ˆ˜์˜ ์‹คํ–‰๊ณผ ๋™์‹œ์— ํ”„๋กœ๋ฏธ์Šค ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๋ฉด์„œ
//pending์ด ์‹œ์ž‘๋˜๋„๋ก ํ•˜๊ธฐ ์œ„ํ•ด ํ”„๋กœ๋ฏธ์Šค ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋ฉด์„œ ๋ฆฌํ„ดํ•˜๋Š” ํ•จ์ˆ˜ p๋ฅผ ๋งŒ๋“ค์–ด์ค€๋‹ค.
//ํ•จ์ˆ˜ p์˜ ์‹คํ–‰๊ณผ ๋™์‹œ์— then ์„ ์„ค์ •ํ•œ๋‹ค.

function p(){
    return new Promise((resolve,reject) => {
        // pending
        setTimeout(() => {
            resolve();  //fullfilled
        },1000);
    });
}

p().then(() => {
    console.log('1000ms ํ›„์— fullfilled ๋ฉ๋‹ˆ๋‹ค.');
});

  • receted ๋˜๋Š” ์‹œ์ ์— p.catch ์•ˆ์— ์„ค์ •ํ•œ callback ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋œ๋‹ค.
function p(){
    return new Promise((resolve,reject) => {
        // pending
        setTimeout(() => {
            reject();  //rejected
        },1000);
    });
}

p()
		// resolve ๋์„ ๋•Œ then 
    .then(() => {
        console.log('1000ms ํ›„์— fullfilled ๋ฉ๋‹ˆ๋‹ค.');
    })
		// reject ๋์„ ๋•Œ catch
    .catch(() => {
        console.log('1000ms ํ›„์— rejected ๋ฉ๋‹ˆ๋‹ค.');
    });

// ์ถœ๋ ฅ : 1000ms ํ›„์— rejected ๋ฉ๋‹ˆ๋‹ค.

resolve ํ•จ์ˆ˜ & reject ์— ์ธ์ž ๋„ฃ๊ธฐ

  • resolve ํ•จ์ˆ˜์— ์ธ์ž๋ฅผ ๋„ฃ์–ด์„œ ์‹คํ–‰ํ•˜๋ฉด, then์˜ callback ํ•จ์ˆ˜์˜ ์ธ์ž๋กœ ๋ฐ›์„ ์ˆ˜ ์žˆ์Œ
  • reject ํ•จ์ˆ˜์— ์ธ์ž๋ฅผ ๋„ฃ์–ด์„œ ์‹คํ–‰ํ•˜๋ฉด, catch์˜ callback ํ•จ์ˆ˜์˜ ์ธ์ž๋กœ ๋ฐ›์„ ์ˆ˜ ์žˆ์Œ
  • ๐Ÿ”ฅ ๋ฐ์ดํ„ฐ๋ฅผ ์„œ๋ฒ„์—์„œ ๋ฐ›์•„์™€์„œ ์ฒ˜๋ฆฌํ•˜๊ธฐ์— ์ข‹๋‹ค!
function p(){
    return new Promise((resolve,reject) => {
        // pending
        setTimeout(() => {
            resolve('hello');  //then์œผ๋กœ ์ธ์ž๋ฅผ ๋ณด๋ƒ„
        },1000);
    });
}

p()
    .then((message) => {
        console.log('1000ms ํ›„์— fullfilled ๋ฉ๋‹ˆ๋‹ค.',message);
    })
    .catch(() => {
        console.log('1000ms ํ›„์— rejected ๋ฉ๋‹ˆ๋‹ค.');
    });


//์—๋Ÿฌ ๊ฐ์ฒด ๋ณด๋‚ด๊ธฐ
function p(){
    return new Promise((resolve,reject) => {
        // pending
        setTimeout(() => {
            reject(new Error('Network Error'));  //then์œผ๋กœ ์ธ์ž๋ฅผ ๋ณด๋ƒ„
        },1000);
    });
}

p()
    .then((message) => {
        console.log('1000ms ํ›„์— fullfilled ๋ฉ๋‹ˆ๋‹ค.',message);
    })
    .catch((error) => {
        console.log('1000ms ํ›„์— rejected ๋ฉ๋‹ˆ๋‹ค.', error);
    });

finally ํ•จ์ˆ˜

  • fullfilled ๋˜๊ฑฐ๋‚˜ rejected ๋œ ํ›„์— ์ตœ์ข…์ ์œผ๋กœ ์‹คํ–‰ํ•  ๊ฒƒ์ด ์žˆ๋‹ค๋ฉด, .finally() ๋ฅผ ์„ค์ •ํ•˜๊ณ , ํ•จ์ˆ˜๋ฅผ ์ธ์ž๋กœ ๋„ฃ์–ด์ฃผ๋ฉด ๋œ๋‹ค.
function p(){
    return new Promise((resolve,reject) => {
        // pending
        setTimeout(() => {
            reject(new Error('Network Error'));  //then์œผ๋กœ ์ธ์ž๋ฅผ ๋ณด๋ƒ„
        },1000);
    });
}

p()
    .then((message) => {
        console.log('1000ms ํ›„์— fullfilled ๋ฉ๋‹ˆ๋‹ค.',message);
    })
    .catch((error) => {
        console.log('1000ms ํ›„์— rejected ๋ฉ๋‹ˆ๋‹ค.', error);
    })
    // ์ถ”๊ฐ€์ ์œผ๋กœ ์ž‘์—…ํ•ด์ค„ ๊ฒƒ์ด ์žˆ์œผ๋ฉด ์„ค์ •ํ•ด์ค€๋‹ค.
    .finally(()=>{
        console.log('end');
    });

promise ์—†์ด ๋น„๋™๊ธฐ ์ž‘์—… ์ฒ˜๋ฆฌํ•˜๊ธฐ : callback

  • promise๊ฐ€ ์—†์„ ๋• callback hell์— ๋น ์ง€๊ณค ํ–ˆ๋‹ค๊ณ  ํ•œ๋‹ค. . .๐Ÿคฌ
function c(callback){
    setTimeout(()=>{
        callback();
    },1000);
}

c(()=>{
    console.log('1000ms ํ›„์— callback ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.');
})

// ๐Ÿ˜ˆ callback hell : ์ ์  ์ค‘์ฒฉ์ด ๋œ๋‹ค.
c(()=>{
    c(()=>{
        c(()=>{
            console.log('1000ms ํ›„์— callback ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.');
        })
    })
})

// [5์ดˆ๋™์•ˆ ์ถœ๋ ฅํ•˜๊ธฐ]
function increaseAndPrint(n, callback) {
  setTimeout(() => {
    const increased = n + 1;
    console.log(increased);
    if (callback) {
      callback(increased);
    }
  }, 1000);
}

increaseAndPrint(0, n => {
  increaseAndPrint(n, n => {
    increaseAndPrint(n, n => {
      increaseAndPrint(n, n => {
        increaseAndPrint(n, n => {
          console.log('์ž‘์—… ๋!');
        });
      });
    });
  });
});

//์ถœ๋ ฅ :
// 1
// 2
// 3
// 4
// 5
// ์ž‘์—… ๋!

promise ๋กœ ๋น„๋™๊ธฐ ์ž‘์—… ์ฒ˜๋ฆฌํ•˜๊ธฐ

function p(){
    return new Promise((resolve,reject)=>{
        setTimeout(()=>{
            resolve();
        },1000);
    });
}

//1์ดˆ ๋’ค
p().then(() => {
    return p();
})
//2์ดˆ ๋’ค : ํ™”์‚ดํ‘œํ•จ์ˆ˜๋ผ return๊ณผ ์ค‘๊ด„ํ˜ธ ์ƒ๋žต
.then(() => p())
//3์ดˆ ๋’ค
.then(p)
//4์ดˆ ๋’ค
.then(()=>{
    console.log('4000ms ํ›„์— fullfilled ๋ฉ๋‹ˆ๋‹ค.');
})

// ์ค‘์ฒฉ์ด ๋˜์ง€์•Š๊ณ , ์ˆœ์ฐจ์ ์œผ๋กœ chaining ๋œ๋‹ค. ๐Ÿ‘๐Ÿป

function increaseAndPrint(n) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const value = n + 1;
      if (value === 5) {
        const error = new Error();
        error.name = "ValueIsFiveError";
        reject(error);
        return;
      }
      console.log(value);
      resolve(value);
    }, 1000);
  });
}

increaseAndPrint(0).then(increaseAndPrint)
.then(increaseAndPrint)
.then(increaseAndPrint)
.then(increaseAndPrint)
.then(increaseAndPrint)
.catch(e => {
  console.log(e);
});

//์ถœ๋ ฅ :
// 1
// 2
// 3
// 4
// ValueIsFiveError

2. Promise.resolve()

Promise.resolve(/* value */);
  • value์—๋Š” ํ”„๋กœ๋ฏธ์Šค ๊ฐ์ฒด๊ฐ€ ์˜ค๊ฑฐ๋‚˜, ์–ด๋–ค ๊ฐ’์„ ๋„ฃ์–ด์„œ then ๋ฉ”์†Œ๋“œ๋ฅผ ์‹คํ–‰์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.
  • ๋งŒ์•ฝ ํ”„๋กœ๋ฏธ์Šค ๊ฐ์ฒด์ธ์ง€, ๋ฐ์ดํ„ฐ ๊ฐ์ฒด์ธ์ง€ ๋ชจ๋ฅผ ๋•Œ Promise.resolve์˜ ์ธ์ž๋กœ ํ•œ๋ฒˆ ๋„˜๊ธฐ๋ฉด ์•Œ์•„์„œ ์ฒ˜๋ฆฌ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์œ ์šฉํ•˜๋‹ค!
Promise.resolve(new Promise((resolve,reject)=>{
    setTimeout(()=>{
        resolve('doyeon');
    },1000);
})).then((data)=>{
    console.log(
        'ํ”„๋กœ๋ฏธ์Šค ๊ฐ์ฒด์ธ ๊ฒฝ์šฐ, resolve ๋œ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ›์•„์„œ then์ด ์‹คํ–‰๋œ๋‹ค.',
        data
    );
});

Promise.resolve('woong').then(data =>{
    console.log(
        'ํ”„๋กœ๋ฏธ์Šค ๊ฐ์ฒด๊ฐ€ ์•„๋‹Œ ๊ฒฝ์šฐ, then ๋ฉ”์†Œ๋“œ๊ฐ€ ์—†๊ธฐ๋•Œ๋ฌธ์— fullfilled ๋ฉ๋‹ˆ๋‹ค.',
        data
    );
});

3. Promise.reject()

Promise.reject(/* value */);
  • Promise.resolve() ์™€ ๋™์ผํ•˜๋‹ค.
  • ๊ฑฐ์˜ ๋“œ๋ฌผ์ง€๋งŒ ๋ฐ›์ž๋งˆ์ž ์—๋Ÿฌ ์ฒ˜๋ฆฌ๋ฅผ ํ•ด์•ผํ•  ๋•Œ ์œ ์šฉํ•˜๋‹ค.
Promise.reject(new Error('reason'))
    .then(error => {})
    .catch(error =>{
    console.log(error);
});

4. Promise.all()

  • ์—ฌ๋Ÿฌ๊ฐœ์˜ ํ”„๋กœ๋ฏธ์Šค ๊ฐ์ฒด๋ฅผ ๋ฐฐ์—ด๋กœ ๋งŒ๋“ค์–ด ์ธ์ž๋กœ ๋„ฃ๊ณ , Promise.all์„ ์‹คํ–‰ํ•œ๋‹ค.
  • ๋ฐฐ์—ด์˜ ๋ชจ๋“  ํ”„๋กœ๋ฏธ์Šค ๊ฐ์ฒด๋“ค์ด fulfilled ๋˜์—ˆ์„ ๋•Œ, then์˜ ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋œ๋‹ค.
  • ํ”„๋กœ๋ฏธ์Šค ๊ฐ์ฒด๋“ค์˜ resolve ์ธ์ž๊ฐ’์ด ๋ฐฐ์—ด ํ˜•ํƒœ๋กœ then์˜ ํ•จ์ˆ˜์˜ ์ธ์ž๋กœ ๋“ค์–ด์˜จ๋‹ค.
function p(ms){
    return new Promise((resolve,reject) => {
        setTimeout(()=>{
            resolve(ms);
            console.log(ms,'ms ํ›„์— ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.');
        },ms);
    });
}

Promise.all([p(1000), p(2000), p(3000)]).then((messages)=>{
    // resolve์˜ ์ธ์ž๊ฐ€ ๋ฐฐ์—ด ์ฒ˜๋ฆฌ ๋˜์–ด then์˜ ์ธ์ž๋กœ ๋“ค์–ด์˜ด (messages)
    console.log('๋ชจ๋‘ fullfilled ๋œ ์ดํ›„์— ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.',messages)
})

์ถœ๋ ฅ:
1000 ms ํ›„์— ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.
2000 ms ํ›„์— ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.
3000 ms ํ›„์— ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.
๋ชจ๋‘ fullfilled ๋œ ์ดํ›„์— ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. [ 1000, 2000, 3000 ]

5. Promise.race()

  • Promise.all ์€ ๋ชจ๋“  ํ”„๋กœ๋ฏธ์Šค ๊ฐ์ฒด๊ฐ€ fullfilled ๋˜์–ด์•ผ ์‹คํ–‰๋๋‹ค๋ฉด, Promise.race๋Š” ๊ฐ€์žฅ ๋จผ์ € fullfilled ๋œ ๊ฒƒ์œผ๋กœ then์˜ ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋œ๋‹ค.
  • then์˜ ํ•จ์ˆ˜ ์ธ์ž๋กœ ๊ฐ€์žฅ ๋จผ์ € fullfilled ๋œ ํ”„๋กœ๋ฏธ์Šค ๊ฐ์ฒด์˜ resolve ์ธ์ž๊ฐ’์ด ๋“ค์–ด์˜จ๋‹ค.
function p(ms){
    return new Promise((resolve,reject) => {
        setTimeout(()=>{
            resolve(ms);
            console.log(ms,'ms ํ›„์— ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.');
        },ms);
    });
}

Promise.race([p(1000), p(2000), p(3000)]).then((messages)=>{
    // ๊ฐ€์žฅ ๋นจ๋ฆฌ ์‹คํ–‰๋œ resolve(1000)์˜ ์ธ์ž๊ฐ€ ๋ฐฐ์—ด ์ฒ˜๋ฆฌ ๋˜์–ด then์˜ ์ธ์ž๋กœ ๋“ค์–ด์˜ด (messages)
    console.log('๊ฐ€์žฅ ๋น ๋ฅธ ํ•˜๋‚˜๊ฐ€ fullfilled ๋œ ์ดํ›„์— ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.',messages)
})
profile
slow and steady wins the race ๐Ÿข

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