오늘은 underscore.js의 메소드를 구현해보고, 비동기에 대해 학습했다. each, filter, uniq, pluck 등등 메소드를 구현하면서 각종 메소드가 어떻게 동작하는지 생각해봤다. 다음은 each를 구현한 예시이다.
_.each = function (collection, iteratee) {
// TODO: 여기에 코드를 작성합니다.
// 익명함수 iteratee가 collection에 접근
// 차례대로 모든 요소의 값을 담아야 한다.
// collection === 배열이나 객체
// iteratee 반복 당하는 콜백함수
// 배열일 때
if(Object.getPrototypeOf(collection) === Array.prototype){
for (let i = 0; i < collection.length; i++) {
iteratee(collection[i], i, collection);
}
}// 객체일 때
else {
for (let key in collection) {
iteratee(collection[key], key, collection);
}
}
};
JS는 코드를 실행하게 되면 block 런타임에 의해 어느 한 작업이 끝날 때까지 작업이 이루어지지 않는다(). Node.js의 등장으로 Non-block 런타임을 지원하면서 JS에서 비동기적 호출이 가능해졌다. 동기적 호출은 그림과 같이 한 작업이 끝나야 다음 작업이 실행된다. 즉, 후속 작업의 시작이 현 작업의 끝과 동일하다.
반면 비동기적 호출은 같은 런타임에도 호출이 가능하다. 이 덕에 유튜브 등 큰 용량의 파일을 서버로부터 호출하는 동안에도 서버에 다른 요청을 보내 동시에 작업이 이루어질 수 있는 여러 장점이 있다.
대표적인 비동기의 예로 세 가지가 있다.
비동기적 코드를 동기적으로 작동시키고 싶을 땐 콜백을 사용한다. 다만, 그 절차가 너무 길어지면
이와 같은 상황이 발생하기도 한다. 때문에 Promise, async/await 등을 사용하여 그 순서를 정해줄 수 있다. Promise 객체는 비동기 작업이 맞이할 미래의 완료 또는 실패와 그 결과 값을 나타낸다.
function func(callback) {
return new Promise(function(resolve, reject) {
// 실행될 내용
});
});
}
// func 후 호출되는 then()
func().then(function(ele) {
console.log(ele); //
});
// funcs
const funcs = () => {
func(callback)
.then(function(ele) => {
return func(callback)
})
.then(function(ele) => {
return func(callback)
})
}
funcs();
async/await의 경우 더 명료하게 나타낼 수 있다.
const funcs = () => {
const one = await func();
const two = await func();
const three = await func();
const four = await func();
}
funcs();