반응형
Notice
Recent Posts
Recent Comments
Link
250x250
«   2025/07   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
Archives
Today
Total
관리 메뉴

동글이의 STORY

콜백 패턴 본문

Javascript/자바스크립트 패턴

콜백 패턴

dongling 2024. 7. 3. 21:43
728x90
반응형

🔷Callback 패턴?

function foo(callback) {
  const a = 10;
  const b = 20;
  callback(a, b);
}

function boo(a, b) {
  return a + b;
}

foo(boo);
  • 콜백은 함수에 인자로 넣어지는 함수
  • 자바스크립트에선 함수 자체가 객체이기 때문에 함수의 인자로 넣어 줄 수 있음

🔷Callback 을 사용한 비동기 처리

function squareAndCallBack(number) {
  let square;
  setTimeout(() => {
  	square = number * number
  }, 100);
  console.log(square);
}

squareAndCallBack(2);
// undefined
  • 자바스크립트는 setTimeout을 기다려주지 않는다 WebAPI를 호출해 task queue로 넘긴다
  • 바로 콘솔로그를 실행하고 setTimeout의 로직을 실행하기 때문에 square는 undefined이다.

  • setTimeout은 addAsync로 제어를 돌려주어 제어가 호출자에게 반환됨.
  • 호출 시점의 컨텍스트를 유지하는 것은 Closure의 특성 덕분
function squareAndCallBack(number, callback) {
  setTimeout(() => {
  	const square = number * number
  	callback(square)
  }, 100);
}

function consolePrint(value) {
  console.log(value);
}

squareAndCallBack(2, consolePrint);
// 4
  • 위와 같은 비동기 문제를 해결하기 위해 콜백을 사용할 수 있다.
  • setTimeout로직 안에 콜백함수를 넣어주면 로직이 실행된뒤 콜백을 통해 결과를 가지고 무언가를 할 수 있다.

🔷Callback 규칙

  1. 콜백은 맨 마지막에, 오류는 맨 앞에
    fs.readFile('foo.txt', (err, data, callback) => {
        if(err) handleError(err);
        else {
            callback(data);
        }
    })
    
  2. ex)
  3. 오류 전파
    • 일반적으로 비동기식 CPS에서 오류를 callback으로 전달하여 수행
    • 오류를 전달할 때는 return callback(err) 처럼 사용해 early return
  4. 캐치되지 않는 예외
    • uncaughtException은 어플리케이션의 일관성을 보장할 수 없게 만든다비동기 콜백 내부에서 예외를 발생시키면, 그 예외는 이벤트 루프로 이동한다.
      • 위의 예에서 만약 try... catch 구문이 없고 JSON.parse 에서 에러가 발생한다면, 예외가 그대로 이벤트 루프로 이동하고 다음 콜백으로 전파되지 않는다.(위의 그림 참고)
      • 제대로 된 예외를 받고자 한다면, 예외가 발생한 스택과 실행 스택이 같아야한다. 즉, 위와같이 에러가 발생할만한 비동기 코드 내부에서 try catch 로 감싸야 한다.
        • 위의 예시를 기준으로, try ... catch 스택과 parse((err, data) => { })의 스택은 별개의 스택
    • ... try { const parsed = JSON.parse((err, data) => { ... }); } catch { // Error catch return callback(err); } ...
    • 그런데, uncaughtException이 만약 발생한다면, 어쨌든 어플리케이션을 종료하도록 처리하는 것이 좋다.

🔷Async Await와 관련된 처리되지 않는 에러

  • 테스트 코드 작성 중 아래와 같은 테스트가 실패한 이유?
expect(await funcThrowException()).to.be.rejectedWith(..);

// 이렇게 보면 편하다.
expect(
    // ..
    await funcThrowException
    // .. 
).to.be.rejectedWith(..);
  • await 키워드를 만나는 시점에 백그라운드로, 이후에 queue로 들어가지만 다시 call stack에 들어간 시점에 funcThrowExecption에서 던진 에러를 어디에서도 받지 못한다.
  • 바깥의 블락(expect ... to.be.rejectedWith)에서 try ... catch로 감싸주면 에러를 잡을 수 있게 된다.
728x90
반응형

'Javascript > 자바스크립트 패턴' 카테고리의 다른 글

싱글톤 패턴  (0) 2024.07.03
메모이제이션 패턴  (2) 2024.07.03
고차함수 / 커링 / 부분적용함수  (5) 2024.07.03
클로저  (3) 2024.07.03
프라미스 패턴  (0) 2024.07.03