[SEB FE] section 2 unit 3 - [JS /Node] ๋น๋๊ธฐ
Underbar
- ์๋ฐ์คํฌ๋ฆฝํธ ๋ฐฐ์ด ๋ด์ฅ ๋ฉ์๋(forEach, map, filter, reduce ๋ฑ)์ ์๋ฆฌ๋ฅผ ์ดํดํ๋ค.
- ์ฝ๋ฐฑ ํจ์ ์ ๋ฌ์ ์์ ๋กญ๊ฒ ํ ์ ์๋ค.
bareMinimum
// _.identity๋ ์ ๋ฌ์ธ์(argument)๊ฐ ๋ฌด์์ด๋ , ๊ทธ๋๋ก ๋ฆฌํดํฉ๋๋ค.
// ์ด ํจ์๋ underbar์ ๊ธฐ๋ฅ ๊ตฌํ ๋ฐ ํ
์คํธ๋ฅผ ์ํด ์ฌ์ฌ์ฉ๋๋ ํจ์์
๋๋ค.
_.identity = function (val) {
return val
};
// _.take๋ ๋ฐฐ์ด์ ์ฒ์ n๊ฐ์ element๋ฅผ ๋ด์ ์๋ก์ด ๋ฐฐ์ด์ ๋ฆฌํดํฉ๋๋ค.
// n์ด undefined์ด๊ฑฐ๋ ์์์ธ ๊ฒฝ์ฐ, ๋น ๋ฐฐ์ด์ ๋ฆฌํดํฉ๋๋ค.
// n์ด ๋ฐฐ์ด์ ๊ธธ์ด๋ฅผ ๋ฒ์ด๋ ๊ฒฝ์ฐ, ์ ์ฒด ๋ฐฐ์ด์ shallow copyํ ์๋ก์ด ๋ฐฐ์ด์ ๋ฆฌํดํฉ๋๋ค.
_.take = function (arr, n) {
let result = [];
if (n === undefined || n <= 0) return [];
if (n > arr.length) return arr
if (n <= arr.length) {
for (let i = 0; i < n; i++) { // arr.length -1 ์ ํด๋ ํต๊ณผ.. ์?
result.push(arr[i])
}
} return result
};
// _.drop๋ _.take์๋ ๋ฐ๋๋ก, ์ฒ์ n๊ฐ์ element๋ฅผ ์ ์ธํ ์๋ก์ด ๋ฐฐ์ด์ ๋ฆฌํดํฉ๋๋ค.
// n์ด undefined์ด๊ฑฐ๋ ์์์ธ ๊ฒฝ์ฐ, ์ ์ฒด ๋ฐฐ์ด์ shallow copyํ ์๋ก์ด ๋ฐฐ์ด์ ๋ฆฌํดํฉ๋๋ค.
// n์ด ๋ฐฐ์ด์ ๊ธธ์ด๋ฅผ ๋ฒ์ด๋ ๊ฒฝ์ฐ, ๋น ๋ฐฐ์ด์ ๋ฆฌํดํฉ๋๋ค.
_.drop = function (arr, n) {
let result = [];
if (n === undefined || n <= 0) return arr
if (n > arr.length) return [];
if (n <= arr.length) {
result.push(arr[arr.length-1]) // ์๋ฒฝํ ์ดํด๋ ์๊ฐ
}
return result
};
// _.last๋ ๋ฐฐ์ด์ ๋ง์ง๋ง n๊ฐ์ element๋ฅผ ๋ด์ ์๋ก์ด ๋ฐฐ์ด์ ๋ฆฌํดํฉ๋๋ค.
// n์ด undefined์ด๊ฑฐ๋ ์์์ธ ๊ฒฝ์ฐ, ๋ฐฐ์ด์ ๋ง์ง๋ง ์์๋ง์ ๋ด์ ๋ฐฐ์ด์ ๋ฆฌํดํฉ๋๋ค.
// n์ด ๋ฐฐ์ด์ ๊ธธ์ด๋ฅผ ๋ฒ์ด๋ ๊ฒฝ์ฐ, ์ ์ฒด ๋ฐฐ์ด์ shallow copyํ ์๋ก์ด ๋ฐฐ์ด์ ๋ฆฌํดํฉ๋๋ค.
// _.take์ _.drop ์ค ์ผ๋ถ ๋๋ ์ ๋ถ๋ฅผ ํ์ฉํ ์ ์์ต๋๋ค.
_.last = function (arr, n) {
let result = [];
if (n === 0) return []
if (n === undefined || n < 0) return [arr.pop()]
if (n > arr.length) return arr
if (n <= arr.length) {
result.push(arr[arr.length-n], arr.length)
}
return result
};
// _.each๋ ๋ช
์์ ์ผ๋ก ์ด๋ค ๊ฐ์ ๋ฆฌํดํ์ง ์์ต๋๋ค.
_.each = function (collection, iteratee) {
if (Array.isArray(collection)) {
for (let i = 0; i < collection.length; i++) {
iteratee(collection[i], i, collection)
}
} else {
for (let obj in collection) { //of ์ผ๋ค๊ฐ ํ๋ฆผ
iteratee(collection[obj], obj, collection)
}
}
};
// _.indexOf๋ target์ผ๋ก ์ ๋ฌ๋๋ ๊ฐ์ด arr์ ์์์ธ ๊ฒฝ์ฐ, ๋ฐฐ์ด์์์ ์์น(index)๋ฅผ ๋ฆฌํดํฉ๋๋ค.
// ๊ทธ๋ ์ง ์์ ๊ฒฝ์ฐ, -1์ ๋ฆฌํดํฉ๋๋ค.
// target์ด ์ค๋ณตํด์ ์กด์ฌํ๋ ๊ฒฝ์ฐ, ๊ฐ์ฅ ๋ฎ์ index๋ฅผ ๋ฆฌํดํฉ๋๋ค.
_.indexOf = function (arr, target) {
// ๋ฐฐ์ด์ ๋ชจ๋ ์์์ ์ ๊ทผํ๋ ค๋ฉด, ์ํ ์๊ณ ๋ฆฌ์ฆ(iteration algorithm)์ ๊ตฌํํด์ผ ํฉ๋๋ค.
// ๋ฐ๋ณต๋ฌธ์ ์ฌ์ฉํ๋ ๊ฒ์ด ๊ฐ์ฅ ์ผ๋ฐ์ ์ด์ง๋ง, ์ง๊ธ๋ถํฐ๋ ์ด๋ฏธ ๊ตฌํํ _.each ํจ์๋ฅผ ํ์ฉํ์ฌ์ผ ํฉ๋๋ค.
// ์๋ _.indexOf์ ๊ตฌํ์ ์ฐธ๊ณ ํ์๊ธฐ ๋ฐ๋๋๋ค.
let result = -1;
_.each(arr, function (item, index) {
if (item === target && result === -1) {
result = index;
}
});
return result;
};
// _.filter๋ test ํจ์๋ฅผ ํต๊ณผํ๋ ๋ชจ๋ ์์๋ฅผ ๋ด์ ์๋ก์ด ๋ฐฐ์ด์ ๋ฆฌํดํฉ๋๋ค.
// test(element)์ ๊ฒฐ๊ณผ(return ๊ฐ)๊ฐ truthy์ผ ๊ฒฝ์ฐ, ํต๊ณผ์
๋๋ค.
// test ํจ์๋ ๊ฐ ์์์ ๋ฐ๋ณต ์ ์ฉ๋ฉ๋๋ค.
_.filter = function (arr, test) {
let result = [];
_.each (arr, function (el) {
if (test(el)) {
result.push(el)
}
})
return result
};
// _.reject๋ _.filter์ ์ ๋ฐ๋๋ก test ํจ์๋ฅผ ํต๊ณผํ์ง ์๋ ๋ชจ๋ ์์๋ฅผ ๋ด์ ์๋ก์ด ๋ฐฐ์ด์ ๋ฆฌํดํฉ๋๋ค.
_.reject = function (arr, test) {
let result = [];
_.each (arr, function (el) {
if (!test(el)) {
result.push((el))
}
})
return result
// TIP: ์์์ ๊ตฌํํ `filter` ํจ์๋ฅผ ์ฌ์ฉํด์ `reject` ํจ์๋ฅผ ๊ตฌํํด ๋ณด์ธ์.
};
// _.uniq๋ ์ฃผ์ด์ง ๋ฐฐ์ด์ ์์๊ฐ ์ค๋ณต๋์ง ์๋๋ก ์๋ก์ด ๋ฐฐ์ด์ ๋ฆฌํดํฉ๋๋ค.
// ์ค๋ณต ์ฌ๋ถ์ ํ๋จ์ ์๊ฒฉํ ๋์น ์ฐ์ฐ(strict equality, ===)์ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
// ์
๋ ฅ์ผ๋ก ์ ๋ฌ๋๋ ๋ฐฐ์ด์ ์์๋ ๋ชจ๋ primitive value๋ผ๊ณ ๊ฐ์ ํฉ๋๋ค.
_.uniq = function (arr) {
let result = [];
_.each (arr, function (el) {
if(_.indexOf(result, el) === -1 ) {
result.push(el)
}
})
return result
};
// _.map์ iteratee(๋ฐ๋ณต๋๋ ์์
)๋ฅผ ๋ฐฐ์ด์ ๊ฐ ์์์ ์ ์ฉ(apply)ํ ๊ฒฐ๊ณผ๋ฅผ ๋ด์ ์๋ก์ด ๋ฐฐ์ด์ ๋ฆฌํดํฉ๋๋ค.
// ํจ์์ ์ด๋ฆ์์ ๋๋ฌ๋๋ฏ์ด _.map์ ๋ฐฐ์ด์ ๊ฐ ์์๋ฅผ ๋ค๋ฅธ ๊ฒ(iteratee์ ๊ฒฐ๊ณผ)์ผ๋ก ๋งคํ(mapping)ํฉ๋๋ค.
_.map = function (arr, iteratee) {
// TODO: ์ฌ๊ธฐ์ ์ฝ๋๋ฅผ ์์ฑํฉ๋๋ค.
// _.map ํจ์๋ ๋งค์ฐ ์์ฃผ ์ฌ์ฉ๋ฉ๋๋ค.
// _.each ํจ์์ ๋น์ทํ๊ฒ ๋์ํ์ง๋ง, ๊ฐ ์์์ iteratee๋ฅผ ์ ์ฉํ ๊ฒฐ๊ณผ๋ฅผ ๋ฆฌํดํฉ๋๋ค.
let newArr = [];
_.each(arr, function (el) {
// iterateee
newArr.push(iteratee(el));
});
return newArr;
};
// _.pluck์
// 1. ๊ฐ์ฒด ๋๋ ๋ฐฐ์ด์ ์์๋ก ๊ฐ๋ ๋ฐฐ์ด๊ณผ ๊ฐ ์์์์ ์ฐพ๊ณ ์ ํ๋ key ๋๋ index๋ฅผ ์
๋ ฅ๋ฐ์
// 2. ๊ฐ ์์์ ํด๋น ๊ฐ ๋๋ ์์๋ง์ ์ถ์ถํ์ฌ ์๋ก์ด ๋ฐฐ์ด์ ์ ์ฅํ๊ณ ,
// 3. ์ต์ข
์ ์ผ๋ก ์๋ก์ด ๋ฐฐ์ด์ ๋ฆฌํดํฉ๋๋ค.
// ์๋ฅผ ๋ค์ด, ๊ฐ ๊ฐ์ธ์ ์ ๋ณด๋ฅผ ๋ด์ ๊ฐ์ฒด๋ฅผ ์์๋ก ๊ฐ๋ ๋ฐฐ์ด์ ํตํด์, ๋ชจ๋ ๊ฐ์ธ์ ๋์ด๋ง์ผ๋ก ๊ตฌ์ฑ๋ ๋ณ๋์ ๋ฐฐ์ด์ ๋ง๋ค ์ ์์ต๋๋ค.
// ์ต์ข
์ ์ผ๋ก ๋ฆฌํด๋๋ ์๋ก์ด ๋ฐฐ์ด์ ๊ธธ์ด๋ ์
๋ ฅ์ผ๋ก ์ ๋ฌ๋๋ ๋ฐฐ์ด์ ๊ธธ์ด์ ๊ฐ์์ผ ํฉ๋๋ค.
// ๋ฐ๋ผ์ ์ฐพ๊ณ ์ ํ๋ key ๋๋ index๋ฅผ ๊ฐ์ง๊ณ ์์ง ์์ ์์์ ๊ฒฝ์ฐ, ์ถ์ถ ๊ฒฐ๊ณผ๋ undefined ์
๋๋ค.
_.pluck = function (arr, keyOrIdx) {
// _.pluck์ _.each๋ฅผ ์ฌ์ฉํด ๊ตฌํํ๋ฉด ์๋์ ๊ฐ์ต๋๋ค.
// let result = [];
// _.each(arr, function (item) {
// result.push(item[keyOrIdx]);
// });
// return result;
// _.pluck์ _.map์ ์ฌ์ฉํด ๊ตฌํํ์๊ธฐ ๋ฐ๋๋๋ค.
return _.map (arr, function (item) {
return item[keyOrIdx]
})
};
//reduce ์ค๋ช
์๋ต
_.reduce = function (arr, iteratee, initVal) {
// TODO: ์ฌ๊ธฐ์ ์ฝ๋๋ฅผ ์์ฑํฉ๋๋ค.
// ์ผ๋จ ๋์ ๊ฐ์ ๊ตฌํด์ผ ํ๋๊น initVal๋ฅผ ๋ณ์ result์ ํ ๋น
// arr์์๋ฅผ ๋๋ฉด์ iterateeํจ์์ ๋ฐ๋ผ result์ ์ค์ฒฉ
// initVal๊ฐ undefined ๊ฑฐ๋ 0 ์ผ๋
let result = initVal;
_.each(arr, function (ele, idx, collection) {
// ์ด๊ธฐ๊ฐ ์ค์ ๋์์ง ์์ ๊ฒฝ์ฐ
if(initVal === undefined && idx === 0) { /// ์ idx === 0 ์ด ์์ด์ผ ํ๋๊ฐ??
result = ele;
}
else {
result = iteratee(result, ele, idx, collection);
}
})
return result;
};
๋น๋๊ธฐ
- client : '์๋ฒ๋ก ์ ์ํ๋ ์ปดํจํฐ' (๋ณดํต ์ฐ๋ฆฌ์ ์ปดํจํฐ)
- Server : '๋ฌด์ธ๊ฐ(์๋น์ค, ๋ฆฌ์์ค ๋ฑ)์ ์ ๊ณตํ๋ ์ปดํจํฐ (์น, ๊ฒ์ ์๋ฒ ๋ฑ)
Callback
์์๋ฅผ ์ ์ดํ๊ณ ์ถ์ ๊ฒฝ์ฐ
const printString = (string) => {
setTimeout(
() => {
console.log(string)
},
Math.floor(Math.random() * 100) + 1
)
}
const printAll = () => {
printString("A")
printString("B")
printString("C")
}
printAll() // ?????????
์์ฐจ์ ์ผ๋ก A,B,C๋ฅผ ์ ์ดํ ์๊ฐ ์๋ค
๊ทธ๋์ ์ฝ๋ฐฑํจ์๋ฅผ ์ฌ์ฉ
const printString = (string, callback) => {
setTimeout(
() => {
console.log(string)
callback()
},
Math.floor(Math.random() * 100) + 1
)
}
const printAll = () => {
printString("A", () => {
printString("B", () => {
printString("C", () => {})
})
})
}
printAll() // now ????????
callback ํจ์๋ฅผ ๋ฐ์ ์คํํด์ฃผ๊ณ ,
A๋ฅผ ์คํํ๊ณ , ๋ callback์ ๋ฐ์ ๋๊น
callback ํจ์ ์์์ B๋ฅผ ์คํํ๊ณ ๋๋ค๋ฅธ callback
....
ABC ์์๋ฅผ ์ง์ผ์ ์ถ๋ ฅ
const somethingGonnaHappen = callback => {
waitingUntilSomethingHappens ()
if (isSomethingGood) {
callback(null, something) // callback์ ์ธ์๋ฅผ ๋๊ฒจ ์ค
}
if (isSomethingBad) {
callback(something, null)
}
}
somethingGonnaHappen((err, data) => {
if (err) {
console.log('ERR!!');
return;
}
return data;
})
์ฌ์ฉ์๋ฅผ ๊ณ ๋ คํด์ ์ ์ด์ ์ฝ๋ฐฑ์ ์ธ์๋ก ๋ฐ์์ ์ค๊ณ ๊ฐ๋ฅ
์ผ๋ฐ์ ์ผ๋ก๋ ์์ ์๋ฌ๋ฅผ ์ฃผ๊ณ ๋ค์ ๋ฐ์ดํฐ๋ฅผ ๋ฃ์ด ์ค๋ค.
์์ผ๋ก API๋ library๋ฅผ ์ฐ๋ ์์ ์๋ฌ๋ฅผ ์ฐ๊ณ ๋ค์ ๊ฒฐ๊ณผ๊ฐ์ ๊ฐ์ง๊ณ ์ค๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ด ์๊ธธ ๊ฒ์
Promise
const printString = (string) => {
return new Promise((resolve, reject) => { //promise ๋์ ์ฝ๋ฐฑ์ ๋ฐ์
setTimeout(
() => {
console.log(string)
resolve() // ์์์ ์ธ์๋ก ๋ฐ์๋ resolve๋ฅผ ๋ฐ์
// ๋ง์ฝ ์๋ฌ๊ฐ ๋ฐ์ํ๋ ๊ฒฝ์ฐ์ reject๋ ์ฌ์ฉ
},
Math.floor(Math.random() * 100) + 1
)
})
}
const printAll = () => {
printString("A")
.then(() => { // .then์ผ๋ก ์ด์ด๋๊ฐ ์ ์์
// printString์ด ๋๋๋ฉด ๋ค์ ํจ์๋ฅผ ์คํํด์ค~
return printString("B")
})
.then(() => {
return printString("C")
})
}
printAll()
๋์์ ์ฝ๋ฐฑ๊ณผ ๋์ผํ๊ฒ ๋์
์ฒซ ํ
์คํฌ๊ฐ ๋๋๊ณ ๋์ ๋ค์ ํ์คํฌ๋ฅผ ์งํํ ์ ์๋ค
๊ธฐ์กด์ ์ฝ๋ฐฑ์์ ์๋ฌ๋ฅผ ๋๊ฒจ์ฃผ๋ ํจ์๋ฅผ ์ด์ฉํ๋ค๋ฉด -> ์ฝ๋ฐฑ์ ์ฒ๋ฆฌํ ๋๋ง๋ค ์๋ฌ์ฒ๋ฆฌ๋ฅผ ํด์ค์ผํจ
๊ทผ๋ฐ ํ๋ก๋ฏธ์ค๋ฅผ ์ฌ์ฉํ๋ฉด .then, .then -- ํด์ ๋ง์ง๋ง์ catch๋ฅผ ์ด์ฉํด ์๋ฌ๋ฅผ ์ก์ ๋ผ ์ ์๋ค.
ํ์ง๋ง Promise๋ฅผ ํ์ฉํ ๋ฐฉ์ ์ญ์ Callback ํจ์๋ฅผ ์ด์ฉํ ๋ฐฉ๋ฒ๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก ๋ฉ์๋๋ค์ด ์์ฒญ๋๊ฒ ์ค์ฒฉ๋๊ฒ ๋๋ฉด ์ฝ๋์ ๊ฐ๋ ์ฑ์ด ๋จ์ด์ง๊ฒ ๋๋ค. (Promise Hell)
function wakeUp() {
return new Promise((resolve, reject) => {
setTimeout(() => { resolve('wake up') }, 100)
})
}
function dailyCoding() {
return new Promise((resolve, reject) => {
setTimeout(() => { resolve('dailyCoding') }, 100)
})
}
function haveMeal() {
return new Promise((resolve, reject) => {
setTimeout(() => { resolve('haveMeal') }, 100)
})
}
function lol() {
return new Promise((resolve, reject) => {
setTimeout(() => { resolve('lol') }, 100)
})
}
wakeUp()
.then(data => {
console.log(data)
dailyCoding()
.then(data => {
console.log(data)
haveMeal()
.then(data => {
console.log(data)
lol()
.then(data => {
console.log(data)
})
})
})
})
promise hell
โฌ๏ธ
promise chain
wakeUp()
.then(data => {
console.log(data)
return haveMeal()
})
.then(data => {
console.log(data)
return drinkSoju()
})
.then(data => {
console.log(data)
return sleep()
})
.then(data => {
console.log(data)
})
ASYNC / AWAIT
const result = async () => {
const one = await wakeUp();
console.log(one)
const two = await dailyCoding();
console.log(two)
const three = await haveMeal();
console.log(three)
const four = await lol();
console.log(four)
}
result (); // wake up, dailyCoding, haveMeal, lol
๋น๋๊ธฐ ํจ์๋ค์ ๋ง์น ๋๊ธฐ์ ์ธ ํ๋ก๊ทธ๋จ์ธ ๊ฒ์ฒ๋ผ ์ฌ์ฉ.
function wakeUp() {
return new Promise((resolve, reject) => {
setTimeout(() => { resolve('wake up') }, 200)
})
}
function dailyCoding() {
return new Promise((resolve, reject) => {
setTimeout(() => { resolve('dailyCoding') }, 100)
})
}
function haveMeal() {
return new Promise((resolve, reject) => {
setTimeout(() => { resolve('haveMeal') }, 500)
})
}
function lol() {
return new Promise((resolve, reject) => {
setTimeout(() => { resolve('lol') }, 10)
})
}
undefined
const result = async () => {
const one = await wakeUp();
console.log(one)
const two = await dailyCoding();
console.log(two)
const three = await haveMeal();
console.log(three)
const four = await lol();
console.log(four)
}
์๊ฐ์ ๋ณ๊ฒฝํด๋ ์กฐ๊ธ ๋ฆ๊ฒ ์คํ๋ ๋ฟ ์์ฐจ์ ์ผ๋ก ์ถ๋ ฅ