์ฃผ๋‹ˆ์–ด ๊ฐœ๋ฐœ์ž์˜ ๊ฐœ์ธ ๊ณต๋ถ€ ๊ณผ์ •์„ ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค.


์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ž€?

์ฝœ๋ฐฑ ํ•จ์ˆ˜(callback function)๋ž€, ๋‹ค๋ฅธ ์ฝ”๋“œ์˜ ์ธ์ž๋กœ ๋„˜๊ฒจ์ฃผ๋Š” ํ•จ์ˆ˜

์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ๋„˜๊ฒจ๋ฐ›์€ ์ฝ”๋“œ๋Š” ์ด ์ฝœ๋ฐฑ ํ•จ์ˆ˜์—๊ฒŒ ์ œ์–ด๊ถŒ์„ ๋„˜๊ฒจ ์ฃผ๋ฉฐ, ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋Š” ํ•„์š”์— ๋”ฐ๋ผ ์ ์ ˆํ•œ ์‹œ์ ์— ์‹คํ–‰ํ•œ๋‹ค.


:: โœจ์ œ์–ด๊ถŒ

์˜ˆ์ œ)

let count = 0;
const cbFunc = () => {
  console.log(count);
  if (++count > 4) clearInterval(time);
};

const timer = setInterval(cbFunc, 300);
// ์‹คํ–‰ ๊ฒฐ๊ณผ
// 0 (0.3์ดˆ)
// 1 (0.6์ดˆ)
// 2 (0.9์ดˆ)
// 3 (1.2์ดˆ)
// 4 (1.5์ดˆ)

์˜ˆ์ œ๋ฅผ ํ†ตํ•ด ์ฝ”๋“œ ์‹คํ–‰ ๋ฐฉ์‹๊ณผ ์ œ์–ด๊ถŒ์„ ์‚ดํŽด๋ณด๋ฉด,

code ํ˜ธ์ถœ ์ฃผ์ฒด ์ œ์–ด๊ถŒ
cbFunc(); ์‚ฌ์šฉ์ž ์‚ฌ์šฉ์ž
setInterval(cbFunc, 300); setInterval setInterval
  • setInterval์ด๋ผ๊ณ  ํ•˜๋Š” โ€˜๋‹ค๋ฅธ ์ฝ”๋“œโ€™์— ์ฒซ ๋ฒˆ์งธ ์ธ์ž๋กœ์„œ cbFunc ํ•จ์ˆ˜๋ฅผ ๋„˜๊ฒจ์ฃผ์ž
  • ์ œ์–ด๊ถŒ์„ ๋„˜๊ฒจ๋ฐ›์€ setInterval์ด ์Šค์Šค๋กœ์˜ ํŒ๋‹จ์— ๋”ฐ๋ผ ์ ์ ˆํ•œ ์‹œ์ ์—(0.3์ดˆ ๋งˆ๋‹ค) ์ด ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ–ˆ๋‹ค.
  • ์ฝœ๋ฐฑ ํ•จ์ˆ˜์˜ ์ œ์–ด๊ถŒ์„ ๋„˜๊ฒจ๋ฐ›์€ ์ฝ”๋“œ๋Š” ์ฝœ๋ฐฑ ํ•จ์ˆ˜ ํ˜ธ์ถœ ์‹œ์ ์— ๋Œ€ํ•œ ์ œ์–ด๊ถŒ์„ ๊ฐ€์ง„๋‹ค.
  • ์ œ์–ด๊ถŒ์„ ๋„˜๊ฒจ๋ฐ›์€ ์ฝ”๋“œ๋Š” ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ ์ธ์ž์— ์–ด๋–ค ๊ฐ’๋“ค์„ ์–ด๋–ค ์ˆœ์„œ๋กœ ๋„˜๊ธธ ๊ฒƒ์ธ์ง€์— ๋Œ€ํ•œ ์ œ์–ด๊ถŒ๋„ ๊ฐ€์ง„๋‹ค.

:: โœ”๏ธ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋„ ํ•จ์ˆ˜๋‹ค

const obj = {
	vals: [1, 2, 3],
  	logValues: (v, i) => {
    	console.log(v, i)
    };
};
obj.logValues(1, 2); // (1)
// {vals:[1, 2, 3], logValues: f} 1 2
[4, 5, 6].forEach(obj.logValues);  // (2)
// Window {...} 4 0
// Window {...} 5 1
// Window {...} 6 2

(1) ์ด๋ฆ„ ์•ž์— ์ (.)์ด ์žˆ์œผ๋‹ˆ ๋ฉ”์„œ๋“œ๋กœ์„œ ํ˜ธ์ถœ โ€ โž” ์ด ๋•Œ์˜ this๋Š” obj (2) ํ•จ์ˆ˜๋งŒ ์ „๋‹ฌ ๋ฐ›์€ ๊ฒƒ์œผ๋กœ, obj์™€ ์—ฐ๊ด€์ด ์—†์–ด์ง„๋‹ค. โ€ โž” ์ด ๋•Œ์˜ this๋Š” ์ „์—ญ ๊ฐ์ฒด(window)

โž” ์ฝœ๋ฐฑ ํ•จ์ˆ˜ ๋‚ด๋ถ€์˜ this์— ๋‹ค๋ฅธ ๊ฐ’ ๋ฐ”์ธ๋”ฉํ•˜๊ธฐ

๋ณ„๋„์˜ ์ธ์ž๋กœ this๋ฅผ ๋ฐ›๋Š” ํ•จ์ˆ˜์˜ ๊ฒฝ์šฐ์—๋Š” ์›ํ•˜๋Š” ๊ฐ’์„ ๋„˜๊ฒจ์ฃผ๋ฉด ๋˜์ง€๋งŒ, ๊ทธ๋ ‡์ง€ ์•Š์€ ๊ฒฝ์šฐ์—๋Š” this์˜ ์ œ์–ด๊ถŒ๋„ ๋„˜๊ฒจ์ฃผ๊ฒŒ ๋˜๋ฏ€๋กœ ์‚ฌ์šฉ์ž๊ฐ€ ์ž„์˜๋กœ ๋ฐ”๊ฟ€ ์ˆ˜ ์—†๋‹ค.

:: ์ฝœ๋ฐฑ ํ•จ์ˆ˜ ๋‚ด๋ถ€์˜ this์— ๋‹ค๋ฅธ ๊ฐ’์„ ๋ฐ”์ธ๋”ฉ ํ•˜๋Š” ๋ฐฉ๋ฒ•

(1) ๋ณ€์ˆ˜์— ๋‹ด๊ธฐ

(์ „ํ†ต์ ์ธ ๋ฐฉ์‹) ์ž˜ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค โŒ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋กœ ํ™œ์šฉํ•  ํ•จ์ˆ˜์—์„œ๋Š” this๋ฅผ ๋‹ค๋ฅธ ๋ณ€์ˆ˜์— ๋‹ด์•„ this ๋Œ€์‹  ๊ทธ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ํ•˜๊ณ , ์ด๋ฅผ ํด๋กœ์ €๋กœ ๋งŒ๋“œ๋Š” ๋ฐฉ์‹์ด ๋งŽ์ด ์“ฐ์˜€๋‹ค.


(2) bind ๋ฉ”์„œ๋“œ ํ™œ์šฉ +ES5

const obj = {
	name: 'yrKim',
  	func: () => console.log(this.name);
};

setTimeout(obj.func.bind(obj), 1000);

const obj2 = { name: 'april' }
setTimeout(obj.func.bind(obj2), 1500);

:: ๐Ÿšฉ ์ฝœ๋ฐฑ ์ง€์˜ฅ๊ณผ ๋น„๋™๊ธฐ ์ œ์–ด

์ฝœ๋ฐฑ ์ง€์˜ฅ(callback hell)์€ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ์ต๋ช… ํ•จ์ˆ˜๋กœ ์ „๋‹ฌํ•˜๋Š” ๊ณผ์ •์ด ๋ฐ˜๋ณต๋˜์–ด ์ฝ”๋“œ์˜ ๋“ค์—ฌ์“ฐ๊ธฐ ์ˆ˜์ค€์ด ๊ฐ๋‹นํ•˜๊ธฐ ํž˜๋“ค ์ •๋„๋กœ ๊นŠ์–ด์ง€๋Š” ํ˜„์ƒ์œผ๋กœ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ๋Š” ํ”ํžˆ ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ..๐Ÿฅฒ๐Ÿฅฒ

โž” ๋น„๋™๊ธฐ์ ์ธ ์ฝ”๋“œ: ์ฆ‰์‹œ ์‹คํ–‰์ด โŒ ์•„๋‹Œ, โ€€ ๋ณ„๋„์˜ ์š”์ฒญ, ์‹คํ–‰ ๋Œ€๊ธฐ, ๋ณด๋ฅ˜ ๋“ฑ๊ณผ ๊ด€๋ จ๋œ ์ฝ”๋“œ

(1) +ES6์˜ Promise๋ฅผ ์ด์šฉํ•œ ๋ฐฉ์‹

new Promise((resolve) => {
  setTimeout(() => {
    let name = "์—์Šคํ”„๋ ˆ์†Œ";
    console.log(name);
    resoleve(name);
  }, 500);
})
  .then((prevName) => {
    new Promise((resolve) => {
      setTimeout(() => {
        let name = prevName + ", ์•„๋ฉ”๋ฆฌ์นด๋…ธ";
        console.log(name);
        resoleve(name);
      }, 500);
    });
  })
  .then((prevName) => {
    new Promise((resolve) => {
      setTimeout(() => {
        let name = prevName + ", ์นดํŽ˜๋ผ๋–ผ";
        console.log(name);
        resoleve(name);
      }, 500);
    });
  });
  • promise์˜ ์ธ์ž๋กœ ๋„˜๊ฒจ์ฃผ๋Š” ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋Š” ํ˜ธ์ถœํ•  ๋•Œ ๋ฐ”๋กœ ์‹คํ–‰๋˜์ง€๋งŒ
  • ๊ทธ ๋‚ด๋ถ€์— resolve ๋˜๋Š” reject ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ตฌ๋ฌธ์ด ์žˆ์„ ๊ฒฝ์šฐ,
    • ๋‘˜ ์ค‘ ํ•˜๋‚˜๊ฐ€ ์‹คํ–‰๋˜๊ธฐ ์ „๊นŒ์ง€๋Š” .then ๋˜๋Š” ์˜ค๋ฅ˜ ๊ตฌ๋ฌธ catch๋กœ ๋„˜์–ด๊ฐ€์ง€ ์•Š๋Š”๋‹ค
    • ๋น„๋™๊ธฐ ์ž‘์—…์ด ์™„๋ฃŒ๋  ๋•Œ resolve ๋˜๋Š” reject๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ ๋น„๋™๊ธฐ ์ž‘์—…์˜ ๋™๊ธฐ์  ํ‘œํ˜„์ด ๊ฐ€๋Šฅํ•˜๋‹ค

(2) Promise + Async/await

const addCoffee = (name) => {
	return new Promise((resolve) => {
    	setTimeout((
        	resolve(name);
        ), 500);
    });
};

const coffeeMaker = async () => {
	let coffeeList = '';
    const _addCoffee = async (name) => {
    	coffeeList += (coffeeList ? ',' : '') +
        await addCoffee(name);
    }
    await _addCoffee('์—์Šคํ”„๋ ˆ์†Œ');
    console.log(coffeeList);
    await _addCoffee('์•„๋ฉ”๋ฆฌ์นด๋…ธ');
    console.log(coffeeList);
    await _addCoffee('์นดํŽ˜๋ผ๋–ผ');
    console.log(coffeeList);
    await _addCoffee('์นดํŽ˜๋ชจ์นด');
    console.log(coffeeList);
};

coffeeMaker();

ES2017์—์„œ ๋“ฑ์žฅํ•œ Async/await๋Š” ๊ฐ€๋…์„ฑ์ด ๋›ฐ์–ด๋‚˜๊ณ , ์ž‘์„ฑ๋ฒ•์ด ๊ฐ„๋‹จํ•˜๋‹ค๋Š” ์žฅ์ ์ด ์žˆ๋‹ค.

  • ๋น„๋™๊ธฐ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๊ณ ์ž ํ•˜๋Š” ํ•จ์ˆ˜ ์•ž์— async ํ‚ค์›Œ๋“œ๋ฅผ ๋ถ™ํ˜€์ฃผ๊ณ ,
  • ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ ์‹ค์งˆ์ ์ธ ๋น„๋™๊ธฐ ์ž‘์—…์ด ํ•„์š”ํ•œ ์œ„์น˜๋งˆ๋‹ค await ํ‚ค์›Œ๋“œ๋ฅผ ๋ถ™ํ˜€์ฃผ๋ฉด
  • ๋’ค์˜ ๋‚ด์šฉ์„ Promise๋กœ ์ž๋™ ์ „ํ™˜ํ•˜๊ณ , ํ•ด๋‹น ๋‚ด์šฉ์ด resolve๋œ ์ดํ›„์— ๋‹ค์Œ์œผ๋กœ ์ง„ํ–‰ํ•œ๋‹ค.

์ฆ‰, Promise์˜ .then๊ณผ ํก์‚ฌํ•œ ํšจ๊ณผ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค.


โœจ tl;dr

  • ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋Š” ๋‹ค๋ฅธ ์ฝ”๋“œ์— ์ธ์ž๋ฅผ ๋„˜๊ฒจ์คŒ์œผ๋กœ์จ ๊ทธ ์ œ์–ด๊ถŒ๋„ ํ•จ๊ป˜ ์œ„์ž„ํ•œ ํ•จ์ˆ˜์ด๋‹ค.
  • ์ œ์–ด๊ถŒ์„ ๋„˜๊ฒจ๋ฐ›์€ ์ฝ”๋“œ๋Š”
    1. ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ์‹œ์ ์„ ์Šค์Šค๋กœ ํŒ๋‹จํ•ด์„œ ์‹คํ–‰
    2. ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ ์ธ์ž๋กœ ๋„˜๊ฒจ์ค„ ๊ฐ’๋“ค ๋ฐ ๊ทธ ์ˆœ์„œ๊ฐ€ ์ •ํ•ด์ ธ ์žˆ๋‹ค. ์ด ์ˆœ์„œ๋ฅผ ๋”ฐ๋ฅด์ง€ ์•Š๊ณ  ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด ์—‰๋šฑํ•œ ๊ฒฐ๊ณผ๋ฅผ ์–ป๊ฒŒ ๋˜๋‹ˆ ์ฃผ์˜!
    3. ์ฝœ๋ฐฑ ํ•จ์ˆ˜์˜ this๊ฐ€ ๋ฌด์—‡์„ ๋ฐ”๋ผ๋ณด๋„๋ก ํ• ์ง€๊ฐ€ ์ •ํ•ด์ ธ ์žˆ๋Š” ๊ฒฝ์šฐ๋„ ์žˆ๋Š”๋ฐ, ์ •ํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ์—๋Š” ์ „์—ญ๊ฐ์ฒด(window)๋ฅผ ๋ฐ”๋ผ๋ณธ๋‹ค.
      • ์‚ฌ์šฉ์ž ์ž„์˜๋กœ this๋ฅผ ๋ฐ”๊พธ๊ณ  ์‹ถ์„ ๊ฒฝ์šฐ bind ๋ฉ”์„œ๋“œ๋ฅผ ํ™œ์šฉํ•˜๋ฉด ๋œ๋‹ค.
  • ์–ด๋–ค ํ•จ์ˆ˜์— ์ธ์ž๋กœ ๋ฒ ์„œ๋“œ๋ฅผ ์ „๋‹ฌํ•˜๋”๋ผ๋„ ๊ฒฐ๊ตญ ํ•จ์ˆ˜๋กœ์„œ ์‹คํ–‰๋œ๋‹ค
  • ๋น„๋™๊ธฐ ์ œ์–ด๋ฅผ ์œ„ํ•œ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ์—” Promise + Async/await ์„ ์ด์šฉํ•˜๋ฉด ๋œ๋‹ค