[Core JavaScript] | April 27, 2021
Core JavaScript(์ฝ์ด ์๋ฐ์คํฌ๋ฆฝํธ) ๋ด์ฉ ์ ๋ฆฌ
setInterval์ ์คํํ๋ฉด ๋ฐ๋ณต์ ์ผ๋ก ์คํ๋๋ ๋ด์ฉ ์์ฒด๋ฅผ ํน์ ํ ์ ์๋ ๊ณ ์ ํ ID ๊ฐ์ด ๋ฐํ๋จ
์ด๋ฅผ ๋ณ์์ ๋ด๋ ์ด์ ๋ ๋ฐ๋ณต ์คํ๋๋ ์ค๊ฐ์ ์ข ๋ฃ(clearInterval)ํ ์ ์๊ฒ ํ๊ธฐ ์ํด์์
var count = 0;
var timer = setInterval(function(){
console.log(count);
if (++count > 4) clearInterval(timer);
}, 300);
timer ๋ณ์์๋ setInterval์ ID ๊ฐ์ด ๋ด๊น
setInterval์ ์ ๋ฌํ ์ฒซ ๋ฒ์งธ ์ธ์์ธ cbFunc ํจ์(์ฝ๋ฐฑ ํจ์)๋ 0.3์ด๋ง๋ค ์๋์ผ๋ก ์คํ๋ ๊ฒ
var count = 0;
var cbFunc = function(){
console.log(count);
if (++count > 4) clearInterval(timer);
};
var timer = setInterval(cbFunc, 300);
>>>
0
1
2
3
4
์ฝ๋ฐฑ ํจ์์ ์ ์ด๊ถ์ ๋๊ฒจ๋ฐ์ ์ฝ๋(setInterval)๋ ์ฝ๋ฐฑ ํจ์ ํธ์ถ ์์ ์ ๋ํ ์ ์ด๊ถ์ ๊ฐ์ง
Code | ํธ์ถ ์ฃผ์ฒด | ์ ์ด๊ถ
-------------------------------------------------------
cbFunc(); | ์ฌ์ฉ์ | ์ฌ์ฉ์
-------------------------------------------------------
setInterval(cbFunc, 300); | setInterval | setInterval
์ฝ๋ฐฑ ํจ์์ ์ ์ด๊ถ์ ๋๊ฒจ๋ฐ์ ์ฝ๋(map)์ ์ฝ๋ฐฑ ํจ์๋ฅผ ํธ์ถํ ๋ ์ธ์์ ์ด๋ค ๊ฐ๋ค์ ์ด๋ค ์์๋ก ๋๊ธธ ๊ฒ์ธ์ง์ ๋ํ ์ ์ด๊ถ์ ๊ฐ์ง
// Array.prototype.map(callback[, thisArg])
// callback: function(currentValue, index, array)
var newArr = [10, 20, 30].map(function(currentValue, index){
console.log(currentValue, index);
return currentValue + 5;
});
console.log(newArr)
>>>
10 0
20 1
30 2
[15, 25, 35]
forEach์ obj๋ฅผ this๋ก ํ๋ method(logValues)๋ฅผ ๊ทธ๋๋ก ์ ๋ฌํ ๊ฒ์ด ์๋๋ผ, obj.logValues๊ฐ ๊ฐ๋ฆฌํค๋ ํจ์๋ง ์ ๋ฌํ ๊ฒ
์ด ํจ์๋ method๋ก์ ํธ์ถํ ๋๊ฐ ์๋ ํ, obj์์ ์ง์ ์ ์ธ ์ฐ๊ด์ด ์์ด์ง
forEach์ ์ํด ์ฝ๋ฐฑ์ด ํจ์๋ก์ ํธ์ถ๋๊ณ , ๋ณ๋๋ก this๋ฅผ ์ง์ ํ๋ ์ธ์๋ฅผ ๋๊ธฐ์ง ์์์ผ๋ฏ๋ก ํจ์ ๋ด๋ถ์์์ this๋ ์ ์ญ๊ฐ์ฒด
var obj = {
logValues: function(v, i){
console.log(this, v, i)
}
};
obj.logValues(1, 2);
>>>
{logValues: f} 1 2
[1, 2, 3].forEach(obj.logValues);
>>>
Window{...} 1 0
Window{...} 2 1
Window{...} 3 2
์ฝ๋ฐฑ ํจ์ ๋ด๋ถ์์ this๊ฐ ํด๋น ๊ฐ์ฒด๋ฅผ ๋ฐ๋ผ๋ณด๊ฒ ํ๊ณ ์ถ๋ค๋ฉด?
โ ์ ํต์ ์ผ๋ก๋ this๋ฅผ ๋ค๋ฅธ ๋ณ์์ ๋ด์ ์ฝ๋ฐฑ ํจ์๋ก ํ์ฉํ ํจ์์์๋ this ๋์ ๊ทธ ๋ณ์๋ฅผ ์ฌ์ฉํ๊ฒ ํ๊ณ , ์ด๋ฅผ ํด๋ก์ ๋ก ๋ง๋๋ ๋ฐฉ์
๊ทธ๋ฌ๋ ์ด ๋ฐฉ์์ ์ค์ ๋ก this๋ฅผ ์ฌ์ฉํ์ง ์์๋ฟ๋๋ฌ ๋ฒ๊ฑฐ๋กญ๋ค.
var obj = {
name: 'obj1',
func: function(){
var self = this;
return function(){
console.log(self.name);
};
}
};
var callback = obj.func();
setTimeout(callback, 1000);
>>> obj1 // 1์ด(1000ms) ๋ค ์คํ
this๋ฅผ ์์ ์ ์ฐ๋ ๋ฐฉ๋ฒ
๊ทธ๋ฌ๋ this๋ฅผ ์ด์ฉํด ๋ค์ํ ์ํฉ์ ์ฌํ์ฉํ ์ ์๋ค.
(์ฒ์๋ถํฐ ๋ฐ๋ผ๋ณผ ๊ฐ์ฒด๋ฅผ ๋ช
์์ ์ผ๋ก obj๋ก ์ง์ ํ๊ธฐ ๋๋ฌธ์ ์ด๋ค ๋ฐฉ๋ฒ์ผ๋ก๋ ๋ค๋ฅธ ๊ฐ์ฒด๋ฅผ ๋ฐ๋ผ๋ณด๊ฒ๋ ํ ์ ์๋ค.)
var obj = {
name: 'obj1',
func: function(){
console.log(obj.name);
}
};
setTimeout(obj.func, 1000);
>>> obj1 // 1์ด(1000ms) ๋ค ์คํ
ES5์์ ๋ฑ์ฅํ bind
method ์ฌ์ฉ (3์ฅ ์ฐธ์กฐ)
var obj1 = {
name: 'obj1',
func: function(){
console.log(this.name);
}
};
setTimeout(obj1.func.bind(obj1), 1000);
>>> obj1 // 1์ด(1000ms) ๋ค ์คํ
var obj2 = {name: 'obj2'};
setTimeout(obj1.func.bind(obj2), 1500);
>>> obj2 // 1.5์ด(1500ms) ๋ค ์คํ
์ฝ๋ฐฑ ์ง์ฅ(callback hell):
์ฝ๋ฐฑ ํจ์๋ฅผ ์ต๋ช
ํจ์๋ก ์ ๋ฌํ๋ ๊ณผ์ ์ด ๋ฐ๋ณต๋์ด ์ฝ๋์ ๋ค์ฌ์ฐ๊ธฐ ์์ค์ด ๊ฐ๋นํ๊ธฐ ํ๋ค ์ ๋๋ก ๊น์ด์ง๋ ํ์
์ฃผ๋ก ์ด๋ฒคํธ ์ฒ๋ฆฌ๋ ์๋ฒ ํต์ ๊ณผ ๊ฐ์ด ๋น๋๊ธฐ์ ์ธ ์์ ์ ์ํํ๊ธฐ ์ํด ์ด๋ฐ ํํ๊ฐ ์์ฃผ ๋ฑ์ฅ
Callback hell ์์
๋ค์ฌ์ฐ๊ธฐ ์์ค์ด ๊ณผ๋ํ๊ฒ ๊น์ + ๊ฐ์ด ์ ๋ฌ๋๋ ์์๊ฐ โ์๋์์ ์๋กโ ํฅํ๊ณ ์์ด ์ด์
setTimeout(function(name){
var coffeeList = name;
console.log(coffeeList);
setTimeout(function(name){
coffeeList += ', ' + name;
console.log(coffeeList);
}, 500, 'Latte');
}, 500, 'Americano');
>>>
Americano
Americano, Latte
Callback hell ํด๊ฒฐ (์ฝ๋ฐฑ ํจ์๋ฅผ ๋ชจ๋ ๊ธฐ๋ช ํจ์๋ก ์ ํ)
์ฝ๋์ ๊ฐ๋ ์ฑ์ ๋์ผ๋ฟ ์๋๋ผ ํจ์ ์ ์ธ๊ณผ ํจ์ ํธ์ถ๋ง ๊ตฌ๋ถํ ์ ์๋ค๋ฉด ์์์๋ถํฐ ์๋๋ก ์์๋๋ก ์ฝ์ด๋ด๋ ค๊ฐ๋ ๋ฐ ์ด๋ ค์์ด ์์
๋ณ์๋ฅผ ์ต์๋จ์ผ๋ก ๋์ด์ฌ๋ฆผ์ผ๋ก์จ ์ธ๋ถ์ ๋ ธ์ถํ๊ฒ ๋์ง๋ง ์ ์ฒด๋ฅผ ์ฆ์ ์คํ ํจ์ ๋ฑ์ผ๋ก ๊ฐ์ธ๋ฉด ํด๊ฒฐ ๊ฐ๋ฅ
But, ์ผํ์ฑ ํจ์๋ฅผ ์ ๋ถ ๋ณ์์ ํ ๋นํ๋ฉด ์ฝ๋๋ช ์ ์ผ์ผ์ด ๋ฐ๋ผ๋ค๋ ์ผ ํ๋ฏ๋ก ํท๊ฐ๋ฆด ์์ง๊ฐ ์์
var coffeeList = '';
var addAmericano = function(name){
coffeeList = name;
console.log(coffeeList);
setTimeout(addLatte, 500, 'Latte');
};
var addLatte = function(name){
coffeeList += ', ' + name;
console.log(coffeeList);
};
setTimeout(addAmericano, 500, 'Americano')
>>>
Americano
Americano, Latte
๋น๋๊ธฐ ์์ ์ด ์๋ฃ๋ ๋ ๋น๋ก์ resolve ๋๋ reject๋ฅผ ํธ์ถํ๋ ๋ฐฉ๋ฒ์ผ๋ก ๋น๋๊ธฐ ์์ ์ ๋๊ธฐ์ ํํ์ด ๊ฐ๋ฅ
new Promise(function(resolve){
setTimeout(function(){
var name = 'Americano';
console.log(name);
resolve(name);
}, 500);
}).then(function(prevName){
return new Promise(function(resolve){
setTimeout(function(){
var name = prevName + ', Latte';
console.log(name);
resolve(name);
}, 500);
});
});
>>>
Americano
Americano, Latte
// ์์ ๋ฐ๋ณต์ ์ธ ๋ด์ฉ์ ํจ์ํ (ํด๋ก์ ๋ 5์ฅ ์ฐธ์กฐ)
var addCoffee = function(name){
return function(prevName){
return new Promise(function(resolve){
setTimeout(function(){
var newName = prevName ? (prevName + ', ' + name) : name;
console.log(newName);
resolve(newName);
}, 500);
});
};
};
addCoffee('Americano')()
.then(addCoffee('Latte'));
>>>
Americano
Americano, Latte
*
์ด ๋ถ์ ํจ์๊ฐ Generator ํจ์์ฆ, ๋น๋๊ธฐ ์์ ์ด ์๋ฃ๋๋ ์์ ๋ง๋ค next method๋ฅผ ํธ์ถํ๋ฉด, Generator ํจ์ ๋ด๋ถ์ ์์๊ฐ ์์์๋ถํฐ ์๋๋ก ์์ฐจ์ ์ผ๋ก ์งํ๋จ
var addCoffee = function(prevName, name){
setTimeout(function(){
coffeeMaker.next(prevName ? prevName + ', ' + name : name);
}, 500);
};
var coffeeGenerator = function*(){
var americano = yield addCoffee('', 'Americano');
console.log(americano);
var latte = yield addCoffee(americano, 'Latte');
console.log(latte);
};
var coffeeMaker = coffeeGenerator();
coffeeMaker.next();
>>>
Americano
Americano, Latte
๋น๋๊ธฐ ์์
์ ์ํํ๊ณ ์ ํ๋ ํจ์ ์์ async
๋ฅผ ํ๊ธฐํ๊ณ , ํจ์ ๋ด๋ถ์์ ์ค์ง์ ์ธ ๋น๋๊ธฐ ์์
์ด ํ์ํ ์์น๋ง๋ค await
๋ฅผ ํ๊ธฐ
โ ๋ค์ ๋ด์ฉ์ Promise๋ก ์๋ ์ ํํ๊ณ , ํด๋น ๋ด์ฉ์ด resolve๋ ์ดํ์์ผ ๋ค์์ผ๋ก ์งํ (Promise์ then๊ณผ ํก์ฌํ ํจ๊ณผ)
var addCoffee = function(name){
return new Promise(function(resolve){
setTimeout(function(){
resolve(name);
}, 500);
});
};
var coffeeMaker = async function(){
var coffeeList = '';
var _addCoffee = async function(name){
coffeeList += (coffeeList ? ',' : '') + await addCoffee(name);
};
await _addCoffee('Americano');
console.log(coffeeList);
await _addCoffee('Latte');
console.log(coffeeList);
};
coffeeMaker();
>>>
Americano
Americano, Latte