๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๊ฐœ๋ฐœ/Javascript

Promise ํŒจํ„ด

by 1mj 2022. 4. 14.

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

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ• ๊นŒ? ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•  ๊ฑฐ๋ฉด ๊ธฐ๋ณธ์ ์ธ ๋™์ž‘ ์›๋ฆฌ์— ๋Œ€ํ•ด์„œ๋Š” ์•Œ์•„์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ๋‹ค.

๊ฐ„๋‹จํ•˜๊ฒŒ ์š”์•ฝํ•˜๋ฉด, ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ์‹ฑ๊ธ€ ์Šค๋ ˆ๋“œ ๊ธฐ๋ฐ˜์ด๊ณ  ์ฝœ๋ฐฑ ํ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

 

 

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์—”์ง„ V8

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์ธํ„ฐํ”„๋ฆฌํ„ฐ ์—ญํ• ์„ ํ•˜๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์—”์ง„์ด ํ•„์š”ํ•˜๋‹ค. ๋Œ€์ค‘์ ์œผ๋กœ ์•Œ๋ ค์ง„ ์—”์ง„์€ ๊ตฌ๊ธ€์˜ V8 ์—”์ง„์œผ๋กœ ํฌ๋กฌ ์›น ๋ธŒ๋ผ์šฐ์ €, Node.js ๋“ฑ์—์„œ ์‚ฌ์šฉ๋˜๊ณ  ์žˆ๋‹ค.

 

V8 ์—”์ง„์˜ ๋‚ด๋ถ€ ๊ตฌ์กฐ๋ฅผ ๊ฐ„๋‹จํžˆ ๋‚˜ํƒ€๋‚ด๋ฉด ์ด๋ ‡๋‹ค. Memory Heap ๊ณผ Call Stack ์ด ์ฃผ์š” ๊ตฌ์„ฑ์š”์†Œ์ด๋‹ค.

  • Memory Heap: ๋ณ€์ˆ˜์™€ ๊ฐ์ฒด์— ๋Œ€ํ•œ ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น์ด ์ผ์–ด๋‚˜๋Š” ๊ณณ
  • Call Stack: ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜๋ฉด ์ˆœ์„œ๋Œ€๋กœ ์Œ“์ด๋Š” ๊ณณ

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

 

๊ทธ๋ž˜์„œ ๊ฐ€๋” ๋ฌดํ•œ ๋ฃจํ”„๋ฅผ ๋„๋Š” ์ฝ”๋“œ๋ฅผ ์ž˜๋ชป ์ž‘์„ฑํ•˜๊ฒŒ ๋˜๋ฉด [Uncaught RangeError: Maximum call stack size exceeded] ๊ฐ™์€ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๊ณค ํ•œ๋‹ค.

 

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

 

 

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ๋Š” ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•ด ์™ธ๋ถ€ API ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๋ฅผ ์™ธ๋ถ€ API ์— ์œ„์ž„ํ•˜๊ณ  ์™„๋ฃŒ๋œ ์ž‘์—…์„ event loop ๋ฅผ ํ†ตํ•ด ๋ฐ˜ํ™˜ ๋ฐ›๊ณ  ๋‹ค์‹œ ์ฝœ๋ฐฑ์„ ์‹คํ–‰ํ•˜์—ฌ ๋ณ‘๋ ฌ์ ์œผ๋กœ ๋น„๋™๊ธฐ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ธ๋‹ค.

  • Call Stack: ์ž‘์—…์ด ์ˆœ์„œ๋Œ€๋กœ ์Œ“์ด๊ณ  ๋๋‚˜๋ฉด ๋น ์ง€๋Š” ๊ณณ
  • Callback Queue: ๋น„๋™๊ธฐ ์ž‘์—…์ด ๋Œ€๊ธฐํ•˜๋‹ค๊ฐ€ Call Stack ์ด ๋น„์–ด์žˆ์œผ๋ฉด Event Loop ์˜ ๋ช…๋ น์— ๋”ฐ๋ผ ์ฐจ๋ก€๋กœ ๋“ค์–ด๊ฐ€๋Š” ๊ณณ
  • Event Loop: ๋น„๋™๊ธฐ/๋™๊ธฐ ์ž‘์—…์˜ ์ˆœ์„œ๋ฅผ ๊ด€๋ฆฌ

 

Call Stack ์—์„œ ์‹คํ–‰๋œ ๋น„๋™๊ธฐ ํ•จ์ˆ˜๋Š” Web API ๋ฅผ ํ˜ธ์ถœํ•˜๊ณ , ์ฝœ๋ฐฑํ•จ์ˆ˜๋ฅผ Callback Queue ์— ๋„ฃ๋Š”๋‹ค. Event Loop ๋Š” Call Stack ์ด ๋นˆ ์ƒํƒœ๊ฐ€ ๋˜๋ฉด Callback Queue ์— ์žˆ๋Š” ์ฒซ ๋ฒˆ์งธ ์ฝœ๋ฐฑ์„ Call Stack ์œผ๋กœ ์ด๋™์‹œํ‚จ๋‹ค.

 

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

 

 

Callback ๋น„๋™๊ธฐ ๋ฌธ์ œ์ 

- ์ฝœ๋ฐฑ ์ง€์˜ฅ

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

 

function getInfo() {
	var myData;
	$.get('info/1', function(response) {
		myData = response;
	});
	return myData;
}
console.log(getInfo());	// undefined

 

์ด๋ฅผ ์ฝœ๋ฐฑํ•จ์ˆ˜๋กœ ํ๋ฆ„ ์ œ์–ด๋ฅผ ํ•ด๋ณด๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

function getInfo(callback) {
	$.get('info/1', function (response) {
    	callback(response);
    })
}
getInfo(function (data) {
	console.log(data);
}) // callback

 

๋‚˜์ค‘์— ์‹คํ–‰์‹œํ‚ค๊ณ ์ž ํ•˜๋Š” ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ๋‹ด์•„ ํ˜ธ์ถœํ•œ๋‹ค. ๊ฑฐ์ณ์•ผ ํ•  ํ•จ์ˆ˜๋“ค์ด ๋งŽ๋‹ค๋ฉด ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ์ต๋ช… ํ•จ์ˆ˜๋กœ ์ „๋‹ฌํ•˜๋Š” ๊ณผ์ •์ด ์ค‘์ฒฉ๋˜์–ด ๋“ค์—ฌ์“ฐ๊ธฐ๊ฐ€ ๊นŠ์–ด์ง€๊ณ  ๊ฐ€๋…์„ฑ์ด ๋–จ์–ด์ง„๋‹ค.

 

- ๊ฒฝ์Ÿ๊ด€๊ณ„ ๋ฐœ์ƒ

์ฝœ๋ฐฑ ์ค‘์ฒฉ ํŒจํ„ด์„ ์šฐํšŒํ•˜๊ธฐ ์œ„ํ•ด ๋‚ด๋ถ€์— ํ”Œ๋ž˜๊ทธ๋ฅผ ์ฃผ๊ณ  ๊ฐ’์ด ๋„์ฐฉํ–ˆ์„ ๋•Œ ์‹คํ–‰ํ•˜๋„๋ก ์ œ์–ดํ•˜๋Š”๋ฐ, ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๋น„๋™๊ธฐ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•œ ๊ฒฝ์šฐ ์–ด๋–ค ํ•จ์ˆ˜๊ฐ€ ๋จผ์ € ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ• ์ง€ ์•Œ์ง€ ๋ชปํ•œ๋‹ค. 

 

 

Promise

๊ทธ๋ž˜์„œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ๋Š” ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๋ฅผ ํ‘œ์ค€ API ํ˜•ํƒœ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ES6์—์„œ ํ”„๋กœ๋ฏธ์Šค(Promise) ๋ฅผ ์ถ”๊ฐ€ํ–ˆ๋‹ค.

Promise ๋Š” ๋น„๋™๊ธฐ์ ์œผ๋กœ ์‹คํ–‰ํ•˜๋Š” ์ž‘์—…์˜ ๊ฒฐ๊ณผ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๊ฐ์ฒด๋กœ ๋น„๋™๊ธฐ์˜ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ์ฒดํ™”์‹œ์ผœ ์‚ฌ์šฉํ•œ๋‹ค.

 

function getInfo(callback) {
  return new Promise(function(resolve, reject) {
    $.get('info/1', function(response) {
      resolve(response);
    });
  });
}

getInfo().then(function(data) {
  console.log(data);
});

 

- Promise ์ƒํƒœ

new Promise() ๋กœ ํ”„๋กœ๋ฏธ์Šค๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์ข…๋ฃŒ๋  ๋•Œ๊นŒ์ง€ 3๊ฐ€์ง€ ์ƒํƒœ๋ฅผ ๊ฐ–๋Š”๋‹ค.

  • Pending (๋Œ€๊ธฐ): ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๊ฐ€ ์•„์ง ์™„๋ฃŒ๋˜์ง€ ์•Š์€ ์ƒํƒœ
  • Fulfilled (์ดํ–‰): ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๊ฐ€ ์™„๋ฃŒ๋˜์–ด ๊ฒฐ๊ณผ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•ด์ค€ ์ƒํƒœ
  • Rejected (์‹คํŒจ): ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๊ฐ€ ์‹คํŒจํ•˜๊ฑฐ๋‚˜ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ ์ƒํƒœ

 

- Promise ์‚ฌ์šฉ ๋ฐฉ๋ฒ•

  • new Promise ์ƒ์„ฑ์ž๋กœ Promise ์ƒ์„ฑ
  • resolve ๋Š” ์„ฑ๊ณต, reject ๋Š” ์‹คํŒจ ์‹œ ์‚ฌ์šฉ
  • then ์‚ฌ์šฉ ์‹œ Promise ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฏ€๋กœ chain ํŒจํ„ด์œผ๋กœ ์‚ฌ์šฉ

 

const myPromise = new Promise(function(resolve, reject) {
  // ...
  // resolve('') or reject('')
});

myPromise
	.then(x => {})	// ์„ฑ๊ณต ์‹œ, ์ธ์ž๋Š” resolve ๊ฐ’
    .catch(x => {})	// ์‹คํŒจ ์‹œ, ์ธ์ž๋Š” reject ๊ฐ’

 

์ฐธ๊ณ ์ž๋ฃŒ ๋ฐ ์ถœ์ฒ˜ ๐Ÿ™‡‍โ™‚๏ธ

https://ljtaek2.tistory.com/142

https://yuddomack.tistory.com/entry/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EC%BD%9C%EB%B0%B1%EC%9D%98-%EB%AC%B8%EC%A0%9C%EC%A0%90%EA%B3%BC-%ED%94%84%EB%A1%9C%EB%AF%B8%EC%8A%A4-%EC%93%B0%EB%8A%94-%EC%9D%B4%EC%9C%A0

https://joshua1988.github.io/web-development/javascript/promise-for-beginners/

 

๋Œ“๊ธ€