[엘리스 SW트랙 4기] 3주차 - Day 14 - 에러처리(try, catch) / 콜백함수, promise, async, await

랸나·2023년 3월 16일
0
post-thumbnail
당장 이해가 되지 않더라도, 꾸준하게 하루에 볼 분량들을 읽고 익숙해지다보면 언젠가는 이해가 확 되는 날이 오겠지..! 
시간이 많이 모자라지만 그래도 성실하고 꾸준하게 해보자.

1. 자바스크립트 에러처리

에러란?

  • 프로그램 실행 중 발생할 수 있는 예외상황들을 Error 라는 일관된 인터페이스로 제공

try catch 구문

  • 에러 객체를 구성하는 요소 세가지 ( name, message, stack)
<script>

console.log('[start]');

try{
	foo();
} catch (error) {
	console.log('[에러발생]', error);
    	// [에러발생] ReferenceError : foo is not defined
    }
console.log('[End]') 
// 발생한 에러에 적절한 대응을 하면 프로그램이 강제종료되지 않음. 

</script>
<script>
try {
	//실행할 코드 (에러 발생 가능성이 있는 코드)
} catch (err){
	// try 코드 블럭에서 에러가 발생하면 이 코드 블럭의 코드가 실행된다.
    // err에는 Try 코드 블럭에서 에러가 발생한 Error 객체가 전달됨
} finally{
	// 에러 발생과 상관없이 반드시 한 번 실행됨. 
}
</script>

Error 객체

생성자 함수인스턴스
Error일반적 에러 객체
SyntaxError자바스크립트 문법에 맞지 않는 문을 해석할 때 발생하는 에러 객체
Reference Error참조할 수 없는 식별자를 참조했을 때 발생하는 에러 객체
TypeError피연산자 또는 인수의 데이터타입이 유효하지 않을 때 발생하는 에러 객체 ex) null[0]
RangeError숫자값의 허용 범위를 벗어났을 때 발생하는 에러 객체
URIErrorEncodeURI 또는 decodeURI함수에 부적절한 인수를 전달했을 때 발생하는 에러 객체
EvalErroreval 함수에서 발생하는 에러 객체

throw 문

  • error 생성자 함수로 에러 객체를 생성한다고 에러가 발생하는 것은 아님. 즉, 에러 객체 생성과 에러 발생은 의미가 다름.
  • throw 표현식;
<script>
try {
	//에러 객체를 던지면 catch 코드 블록이 실행되기 시작한다.
	throw new Error("something wrong");
} catch (over) {
	console.log(error);

}
</script>
<script>
//외부에서 전달받은 콜백 함수를 n번만큼 반복 호출한다.
const repeat = (n, f) => {
	// 매개변수 두번째 인자에 함수가 아니면 TypeError 발생시키기
    if( typeof f!== 'function') throw new TypeError('f must be a function);
    
    for(var i = 0; i < n ; i++){
    	f(i)
        }
}
    
try {
	repeat(2,1); // 두번때 인수가 함수가 아니라 숫자임. 그러면 타입에러 발생
} catch (err) {
	console.error(err); // TypeError : f must be a function
}
</script>

에러의 전파

  • 에러는 호출자 방향으로 전파된다. 즉, 콜스택의 아래방향으로 전파됨.
  • throw된 에러를 캐치하지 않으면 호출자 방향으로 전파됨.
  • 이를 적절히 대응하면 프로그램을 강제 종료 시키지 않고 코드의 실행 흐름을 복구 가능.
  • 비동기함수인 setTimeout이나 프로미스 후속 처리 메서드의 콜백 함수는 호출자가 없음.
  • 에러에서 왜 배열 구조가 아닌 스택 구조를 사용할까? 1) 최소한의 의미를 가진 무언가, 즉 스택을 쓰는게 도움이 됨. 2) 성능적인 차원에서 배열은 생각보다 무거운 자원을 써서 만든 기능.

2. 콜백함수

  • callBack 콜백함수
  • 일급시민, 일급 객체
    val = 1; // 숫자는 변수의 값이 될 수 있음. 일급 시민
    val = if(){} // 조건문은 변수로 불가 > 이급시민
    val = function(){} // 함수는 변수로 가능 > 일급 시민
<script>
function fn(){
	val = function(){
		}
      return val;
// 함수가 다른 함수의 리턴값이 될 수 있다면 일급 시민임

val = function(){
		return 
    }
fn()
// 함수가 다른 함수의 입력값이 될 수 있다면 일급시민임.
</script>

콜백함수 : 다른 함수의 입력값으로 전달되어 다른 함수에 의해서 나중에 호출되는 것.
array.filter 내부에 있는 부분도 콜백함수.

<script>
const words = ['spray', 'limit', 'elite', 'exuberant', 'destruction', 'present'];

const result = words.filter(word => word.length > 6); 
//word => word.length > 6  이것이 콜백함수

console.log(result);
// Expected output: Array ["exuberant", "destruction", "present"]
</script>

콜백함수는 한 번만 사용하는 경우가 많고, 떨어져있으면 응집력이 낮아져서 파라미터 내부 안에 익명함수 형태로 작성하는 경우가 많음.
  • 전통적인 콜백 패턴은 콜백 헬로 인해서 가동성이 나쁘고 비동기 처리 중 발생한 에러의 처리가 곤란함. 여러개의 비동기 처리를 한번에 처리하는데도 한계가 있음. ==> 프로미스의 등장!!

  • 콜백함수 검색하니 나온... 장풍짤 ㅋㅋㅋ 지칠땐 개발자 유머 밈을 보며 낄낄거리곤 하는 내자신.. ^__^..

3. 프로미스

  • 프로미스라는 개념은.. 개발자마자 서로 다른 콜백 방식을 하나의 인터페이스로 통합하자! 라는 의미로 만들어진 것. (우리 서로 힘들지 말게, 이렇게 쓰기로 약속하자~)
<script>
//프로미스 생성
const promise = new Promise(( resolve, reject ) => {
	// Promise 함수의 콜백 함수 내부에서 비동기 처리를 수행한다. 
    if ( /* 비동기 처리 성공 */) {
    	resolve ('result');
   }else { /* 비동기 처리 실패 */
   	reject ('failure reaseon');
   }
});

</script>
  • 프로미스 생성자 함수가 인수로 전달 받은 콜백 함수 내부에서 비동기 처리를 수행한다. 이때 비동기 처리가 성공하면 콜백 함수의 인자로 전달 받은 resolce 함수를 호출하고, 비동기 처리가 실패하면 reject 함수를 호출한다.
  • 어떤 함수의 리턴값이 promise면, 그 함수는 비동기적으로 동작할 가능성이 매우 높음

3-1. 프로미스의 후속 처리 메서드

promise.prototype.then

<script>

//fulfilled
new Promise(resolve => resolve('fulfilled'))
	.then(v => console.log(v), e => console.error(e)); 
    
//rejected
new Promise((-, reject) => reject(new Error('rejected')))
	.then(v=> console.log(v), e=> console.error(e));

</script>
  • then 메서드는 두개의 콜백 함수를 인수로 받는다.
  • 첫번째 콜백은 프로미스가 풀필된 상태가 되면 호출됨. 이때 콜백 함수는 프로미스의 비동기 처리 결과를 인수로 전달받음.
  • 두번째 콜백은 프로미스가 리젝된 상태. 이때 콜백 함수는 프로미스의 에러를 인수로 전달 받음.

promise.prototype.catch

<script>
new Promise((_,reject) => reject(new Error('rejected')))
	.catch(e => console.log(e)); //Error : rejected
</script>
  • catch 메서드는 then과 동일하게 동작함. 따라서 then메서드와 마찬가지로 언제나 프로미스를 반환함.

  • promise.all / promise.race / promiseallSettled...

4. async / await

  • async/await는 프로미스를 기반으로 동작한다. 이 둘을 사용하면 프로미스의 Then/catch/finally후속 처리 메서드에 콜백 함수를 전달해서 비동기 처리 결과를 후속 처리 할 필요 없이 마치 동기 처리처럼 프로미스를 사용할 수 있음.
  • 마치 동기처럼..
  • 아래 코드를 보면 왼쪽에서 오른쪽으로 마치 동기 처리처럼 프로미스를 전달하고 있는 것을 볼 수 있다.


[사진 출처 : 생활코딩 JavaScript - async & await ]

profile
백엔드개발자

0개의 댓글