210316_TIL(fetch API, Event Loop)
✅Toy 문제(isSubsetOf)
두 배열이 주어지고, 한 배열이 나머지 배열의 부분집합인지 여부를 판단하는 문제였다.
처음에는 DFS 알고리즘을 재귀로 구현했었다.
true, false가 나오질 않고, 조건에 안맞아서 포기했다.
결국 나는 for문 내부에 if문을 사용하여 인덱스를 비교하며 결과를 리턴하는 방식으로 해결했다.
다른사람의 풀어본 코드를 볼 수 있었으면 훨씬 좋았을 것 같다.
✅Event Loop

자바스크립트의 큰 특징 중 하나는 '싱글 스레드' 기반의 언어라는 점이다.
호출 스택이 하나라, 동시에 하나의 작업만을 처리할 수 있다.
동작하는 걸 보면 여러 작업이 동시에 처리되기도 한다는 걸 볼 수 있다.
이런 '동시성'을 이해하기 위해 Event Loop에 대해 배웠다.
setTimeout, XMLHTTPRequest 은 자바스크립트 런타임이 아니라 외부에 구현된 webAPI 영역에 존재한다.
이것들은 이벤트 루프를 통해 실행된다.
이벤트 루프는 스택이 비었을 때, task queue의 첫 번째 콜백을 스택에 쌓고 실행시킨다.
'현재 실행중인 task가 없는지', 'task queue에 task가 있는지'를 반복적으로 확인하는 것이다.
실행이 오래걸리는 코드를 적절히 분배하는 등 보다 효율적으로 작동시킬 수 있게 되었다는 것을 알게 되었다.
✅Promise
Promise에 대해 더 자세하게 알아보는 시간이었다.
then, catch, finally 같은 후속처리 메서드들이 각각 어떻게 동작하는지, 그리고 어떤 값을 인자로 받아 무엇을 리턴하는지, 각 메서드의 영향에 대해 mdn문서, 블로그 등을 보고 테스트 코드를 작성해 실행시켜보며 알아보았다.
다른 메서드들은 예상대로 동작했는데 finally의 동작이 예상 밖이었다.
finally는 이름때문인지 가장 마지막에만 써야 할 것 같았는데, 중간에 여러 번 사용할 수도 있고 인자를 받지 않고 리턴도 하지 않는데 마치 터널처럼 이전 함수의 리턴 값을 다음 함수로 넘겨주듯이 동작했다.
then의 리턴값은 분명 프로미스 객체일 텐데 일반적인 값을 얻을 수 있는 것처럼 보였다.
일단 명세서와 콘솔창에서 확인할 수 있듯이 [[PromiseState]]라는 속성의 값에는 프로미스의 상태가(fulfilled, rejected)
[[PromiseResult]] 속성 값에는 resolve나 reject 안에 있던 값이 있는 것을 볼 수 있었다.
이 속성의 값을 꺼내려면 then이나 await를 사용하면 되는데, await을 쓰는 것이 더 안전하다고 한다.
🍒Remember
✅callback & Promise & try/catch


function AsyncFunc (StartText, EndText) {
console.log('\n' + StartText);
return new Promise((resolve, reject) => {
setTimeout(() => {
if(!isErr){
resolve(EndText);
}else{
reject('AsyncFunc : 에러가 났다잉~');
}
}, Math.floor(Math.random() * 2000) + 1);
});
}
AsyncFunc("Name : ", "juhyeon")
.then(function(text){
console.log(text);
});
const run = async() => {
const task = await AsyncFunc("Name : ", "juhyeon");
console.log(task);
}
run();
try, catch 사용
const run = async() => {
const task = await AsyncFunc("Name : ", "juhyeon");
console.log(task);
}catch(err){
console.log(err);
}
}
위에 코드에서 if(!isErr) 빼고는 Name이 두 번 나오는 형식으로 잘 나온다.
VM154:5 Uncaught ReferenceError: isErr is not defined
저 에러코드는 vscode에서도 돌려봐야될 것 같다. (에러코드 검색)
저 에러코드가 안뜨고 작동하게 하려면 5줄에 if(true) 바꾸어서 돌려보면 답이 나온다.
✅fetch를 이용해 웹에서 정보 가져오기
비동기 요청의 가장 대표적인 사례를 꼽으라고 한다면, 단연 네트워크 요청을 들 수 있다.
다양한 네트워크 요청 중, URL로 요청하는 경우가 가장 흔합니다.
이를 가능하게 해주는 API가 바로 fetch API입니다.
최신 뉴스나 날씨/미세먼지 정보가 바로 동적으로 데이터를 받아와야 하는 정보
✅throw & try/catch/finally(Exception Handling)
프로그램이 실행되는 동안 문제가 발생하면 프로그램이 자동으로 중단된다.
이럴 경우에 프로그램이 대처할 수 있도록 처리하는 것이 예외 처리(Exception Handling)라고 합니다.
프로그램 실행 중에 발생하는 오류를 예외(Exception)라고 하고, 프로그래밍 언어의 문법적인 오류를 에러(Error)라고 한다.
예외는 기본 예외 처리와 고급 예외 처리 두 가지 방법으로 처리한다.
예외가 발생하지 않게 사전에 해결하는 것을 기본 예외 처리라고 하며 대개 조건문으로 처리할 수 있다.
아래부터 설명할 내용은 고급 예외 처리이다.
✔️throw(발생시키다.) : 에러나 예외 상황을 알린다는 뜻
✔️catch(잡아내다) : 예외를 잡다, 그것을 처리한다는 뜻(즉 그 예외에서 회복하기 위해 무언가 필요하거나 적절한 행동을 취한다는 뜻이다.)
자바스크립트는 런타임 에러가 일어날 때마다 예외를 발생시킨다.
예외를 강제로 발생시켜야 할 경우가 생길 때는 throw 키워드를 사용한다.
throw 표현식;
// 예제 1
function factorial(x) {
// 만약 전달인자가 유효하지 않으면 예외를 발생시킨다!
if(x < 0){
throw new Error('x는 음수가 아니어야 합니다.')
}
// 유효하다면 값을 계산하여 정상적으로 반환한다.
for(let f = 1; x > 1; f *=x, x--)
return f;
}
그리고 예외를 잡아내는 데에는 try/catch/finally 문을 사용한다.
예외를 강제로 발생시키는 이유는 무엇일까요?
객체를 잘못 사용하는 사용자에게 예외를 강제로 발생시켜서 사용자에게 주의를 줄 수도 있고 예외와 관련된 처리를 해달라고 부탁할 수도 있습니다.
try/catch/finally 문은 자바스크립트의 예외 처리 기법입니다.
예제를 보면서 이해하는 것이 가장 좋은 방법인 것 같다.
try {
// 사용자에게 번호 입력을 요청
let n = prompt("정수를 입력해 주세요.");
// 사용자의 입력이 유효하다고 가정하고 그 숫자의 계승(factorial)을 계산한다.
let f = factorial(n);
// 결과를 표시한다.
console.log(n + "! = " + f);
}catch(ex) { // 만약 사용자의 입력이 유효하지 않다면 이곳에 도달한다.
alert(ex);
}
finally는 catch 만큼 자주 쓰이는 편은 아니지만 종종 유용할 때가 있다. (언제 사용해?)
일단 try 블록이 일부라도 실행되면 finally 절은 실행이 보장된다.
정상적인 경우 try 블록의 끝까지 프로그램 제어가 도달하고 나면 finally 블록으로 제어가 진행하여 무언가 필요한 뒷정리를 수행한다.
만일 return, continue, break 문 등으로 인해 try 블록에서 제어가 빠져나왔다면 이들 문장이 인도하는 곳으로 제어가 이동하기 앞서 finally 블록이 실행된다.
try와 finally는 catch가 없어도 함께 쓰일 수 있다!
이러한 경우 try 절에서 try, continue, return 문 등이 실행된 것과 관계없이, finally 블록은 그저 무조건 실행이 보장되는 뒷정리 코드의 역할을 하게 된다.
try {
fake();
} catch(e){
alert(e.name + ", " + e.message);
}finally{
alert("무조건 실행되는 영역이야!")
}
🍒More Study
✅PromiseChaining, Promise.all, async/await 한번 다시보기
✅Web Architecture
🍉서버에 요청하는 과정에서 예외처리를 안해주면 서버가 죽는다는 소리를 듣고 왜 죽지? 라는 궁금증이 생겼었다.
그 궁금증의 답은 클라이언트가 서버에 요청을 보냈는데, 이 보낸 요청이 정상적인 요청이 아니라면? 서버에서 요청을 받고 예외처리르 못해준다면 프로그램과 서버가 비정상적으로 종료된다. 라고 설명을 할 수 있을 것 같다.
생각보다 예외처리에 대한 심오함에 당황했다.
굉장히 가볍게 생각했었는데 예외처리가 엄청 엄청 중요하다는 걸 깨달았다. 공부하자🤮