[TIL] 비동기와 Promise

Narastro·2021년 8월 3일
0

TIL

목록 보기
10/16
post-thumbnail

😂 비동기에 대해 공부해보자

비동기 함수 동작원리

비동기 함수를 호출하면 함수 내부의 비동기로 동작하는 코드가 완료되지 않았다 해도 기다리지 않고 즉시 종료된다. 즉, 비동기 함수 내부의 비동기로 동작하는 코드는 비동기 함수가 종료된 이후에 완료된다. 따라서 비동기 함수 내부의 비동기로 동작하는 코드에서 처리 결과를 외부로 반환하거나 상위 스코프의 변수로 할당하면 기대한 대로 동작하지 않는다.

Promise 요녀석..

  • Promise는 자바스크립트에서 비동기 처리에 사용되는 객체 (이해가 어려움..ㅠ)
  • Event Emitter에 이벤트를 넣어주고 그걸 프로미스로 받는 아이디어
  • 프로미스의 3가지 상태 <- async/await이 아닌 Promise는 굉장히 생소했다.
    이다.

내 방식

  • 해당 동작을 Event Emitter에 등록한다
  • Event Emitter를 emit하는 클로저를 프로미스 안에 넣어 리턴한다
  • 딜레이함수의 경우 프로미스 내부에 setTimeout을 줬다.

Event Emitter 형태로 비동기 동작을 지원하는 타입

Event Emitter 뜯어보기 - 기술블로그

  • setTimeout
  • setInterval
  • HTTP요청
  • 이벤트 핸들러

내부동작

내부 동작 살펴보기

  • Web API : Web API는 브라우저에서 제공되는 API이다. 자바스크립트 엔진에서 정의되지 않았던 setTimeout이나 HTTP 요청(ajax) 메소드, DOM 이벤트 등의 메소드를 지원한다.
  • Task Queue : 이벤트 발생 후 호출되어야 할 콜백 함수들이 기다리는 공간. 이벤트 루프가 정한 순서대로 줄을 서 있으므로 콜백 큐(Callback Queue) 라고도 한다.
  • Event Loop : 이벤트 발생 시 호출할 콜백 함수들을 관리하고, 호출된 콜백 함수의 실행 순서를 결정한다.

자바스크립트에서 비동기로 호출되는 함수들은 호출 스택(Call Stack)에 쌓이지 않고 태스크 큐(Task Queue)로 보내진다. Event Loop는 Call Stack이 비어있으면 Task Queue에서 함수를 하나씩 꺼내 Call Stack에 넣고 실행한다. 이게 setTimeout() 시간이 정확하지 않을 수도 있는 이유이다.

자바스크립트에서 비동기처리가 필요한 이유

화면에서 서버로 데이터를 요청했을 때 서버가 언제 그 요청에 대한 응답을 할지도 모르는 상태에서 다른 코드를 실행 안하고 기다릴 수는 없기 때문이다.

Promise와 콜백지옥

콜백함수를 여러 개 중첩하면 작업내용을 이해하기 어려워진다. 이것을 콜백 지옥(Callback Hell)이라고도 한다. Promise를 이용하면 콜백 헬을 극복하고 비동기 처리도 간결하게 작성할 수 있다.

Promise를 사용하려면 먼저 Promise객체를 생성해야 한다.

  • resolve : 함수 안의 처리가 끝났을 때 호출해야하는 콜백함수. 어떠한 값도 인수로 넘길 수 있다. 다음 처리를 실행하는 함수에 전달된다.
  • reject : 함수 안의 처리가 실패했을 때 호출해야하는 콜백함수. 어떠한 값도 인수로 넘길수 있다. 주로 오류 메시지 문자열을 인수로 사용한다.

Promise vs async/await

  • 코드 가독성
    callback 이나 Promise 의 경우에 단점은 꼬리에 꼬리를 무는 코드가 나올 수도 있다는 부분이다. 흔히들 콜백 지옥, then() 지옥이라고 부른다.

  • 에러 조작
    Promise 와는 다르게 에러를 핸들링 할 수 있는 기능이 없다. 따라서 try-catch() 문을 활용하여 에러를 핸들링 하여 주어야 한다.

  • 사용법
    await 를 통해 Promise 반환 값을 받아 올 수 있다.
    await 는 async 함수 안에서만 동작한다.

  • 중간값(Intermediate values)
    promise1 을 호출하고 여기서 return된 값을 사용해서 promise2 를 호출하고, promise3 을 호출하기 위해 두개의 promise들의 결과를 사용하는 등 복잡함을 줄여준다.

  • 디버깅이 쉬워진다
    브레이크포인트를 잡기 쉽다

Promise.all

프로미스 여러 개를 한번에 실행할 수 있는 방법이다. 비동기 처리 여러 개를 직렬로 연결해서 순차적으로 실행할 수도 있지만 Promise객체의 all 메서드를 이용하면 비동기 처리 여러 개를 병렬로 할 수 있다.✅

Promise.race

가장 먼저 종료한 Promise객체 결과만을 다음 작업으로 보내는 방법이다. 성공하면 성공 콜백을 호출하고 실패하면 실패 콜백을 호출한다.

🏓 redis 노드 모듈

Redis ?

Redis는 NoSQL 데이타 베이스의 한 종류로, mongoDB 처럼 전체 데이타를 영구히 저장하기 보다는 캐쉬처럼 휘발성이나 임시성 데이타를 저장하는데 많이 사용된다.

디스크에 데이타를 주기적으로 저장하기는 하지만, 이 기능은 백업이나 복구용으로 주로 사용할뿐 데이타는 모두 메모리에 저장되기 때문에, 빠른 접근 속도를 자랑한다.

기능

큐로써의 기능은 하나의 클라이언트가 다른 클라이언트로 메세지를 보내는 1:1 기능뿐 아니라, 하나의 클라이언트가 다수의 클라이언트에게 메세지를 발송하는 발행/배포 (Publish/Subscribe) 기능을 제공한다.

재미있는 것중에 하나는 일반적인 Pub/Sub 시스템의 경우 Subscribe 하는 하나의 Topic에서만 Subscribe하는데 반해서, redis에서는 pattern matching을 통해서 다수의 Topic에서 message 를 subscribe할 수 있다.

예를 들어 topic 이름이 music.pop music,classic 이라는 두개의 Topic이 있을때, "PSUBSCRIBE music.*"라고 하면 두개의 Topic에서 동시에 message를 subscribe할 수 있다.

출처: https://bcho.tistory.com/1098 [조대협의 블로그]

🎯 Observer 패턴과 Publisher-Subscriber 패턴

  • Observer패턴은 Observer와 Subject가 서로를 인지하지만 Pub-Sub패턴의 경우 서로를 전혀 몰라도 상관없다

  • Observer패턴에 비해 Pub-Sub패턴이 더 결합도가 낮다.(Loose Coupling)

  • Observer패턴은 대부분 동기(synchronous) 방식으로 동작하나 Pub-Sub패턴은 대부분 비동기(asynchronous) 방식으로 동작한다.

  • Observer패턴은 단일 도메인 하에서 구현되어야 하나 Pub-Sub패턴은 크로스 도메인 상황에서도 구현 가능하다.

    🥕 느낀점

    Event처리와 비동기 처리에 대해 이해하지 못하고 있음을 느꼈다. 그동안 단순히 비동기처리할 때 쓴다고 알고 있던 async/await 구문을 쓰는 것이 아닌 프로미스를 이용하는 것이 굉장히 미숙했다. 주말에 책을 펴고 프로미스를 보면서 반성한다...(2021/8/8)

profile
Earn this, Earn it.

0개의 댓글