diff --git "a/\354\261\225\355\204\260_9/\353\260\261\354\247\200\354\227\260.md" "b/\354\261\225\355\204\260_9/\353\260\261\354\247\200\354\227\260.md" new file mode 100644 index 0000000..385a6bf --- /dev/null +++ "b/\354\261\225\355\204\260_9/\353\260\261\354\247\200\354\227\260.md" @@ -0,0 +1,76 @@ +# CHAPTER 09 비동기 프로그래밍 패턴 + +비동기 자바스크립트 프로그래밍은 다른 코드를 실행하는 동안 백그라운드에서 오래 걸리는 작업을 수행하게 해줌 +`Promise`, `async/await` 개념은 메인 스레드를 차단하지 않으면서도 코드를 깔끔하고 읽기 쉽게 만들어줌 + +## 비동기 프로그래밍 + +동기 코드는 블로킹 방식으로 실행됨 = 한 번에 한 문장씩 코드가 순서대로 실행됨 +**비동기 코드는 논블로킹 방식으로 실행됨** = 다른 작업을 기다리는 동안 백그라운드에서 비동기 코드 실행 + +코드의 나머지 부분을 차단하지 않고, 오래 실행되는 작업을 수행할 때 유용 +ex. 네트워크 요청, 데이터베이스 읽기/쓰기, 입력/출력 작업 + +## 배경 + +### 콜백 함수 + +다른 함수에 인수로 전달되어, 비동기 작업이 완료된 후 실행됨 +네트워크 요청, 사용자 입력 등 비동기 작업의 결과를 처리하기 위해 사용됨 +콜백 지옥을 초래할 수 있다는 게 단점 + +## 프로미스 패턴 + +프로미스는 비동기 작업의 결과를 나타내는 객체 +`pending`, `fulfilled`, `rejected` 상태를 가질 수 있음 + +`Promise` 생성자는 함수를 인수로 받고, 이 함수는 `resolve`와 `reject`를 인수로 전달받음 +비동기 작업이 성공적으로 완료되었을 때 `resolve` 호출, 실패했을 때 `reject` 호출 + +```javascript +return new Promise((resolve, reject)) => { + fetch(url) + .then(response => response.json()) + .then(data => resolve(data)) + .catch(error => reject(error)); +}; +``` + +- 프로미스 에러 처리 : `catch` 메서드 +- 프로미스 병렬 처리 : `Promise.all` 메서드 +- 프로미스 순차 실행 : `Promise.resolve` 메서드 +- 프로미스 메모이제이션 : 캐시를 사용해 프로미스 함수 호출 결과 저장하고 중복 요청 방지 +- 프로미스 데코레이터 : 고차 함수로 데코레이터를 생성해 프로미스에 추가 기능 부여 +- 프로미스 경쟁 : `Promise.race` 메서드로 여러 프로미스를 동시에 실행하고 가장 먼저 완료되는 프로미스의 결과 반환 + +## async/await 패턴 + +비동기 코드를 마치 동기 코드처럼 작성할 수 있음 +`await` 키워드는 `fetch` 호출이 완료될 때까지 함수 실행을 일시 중지함 + +- 비동기 반복 : [for-await-of](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/for-await...of) 반복문을 사용해 반복 가능 객체를 순회 +- 비동기 에러 처리 : `try-catch` 블록 +- 비동기 병렬 : `Promise.all` 메서드 +- 비동기 순차 실행 : `Promise.resolve` 메서드 +- 비동기 메모이제이션 : 캐시를 사용해 비동기 함수 호출 결과 저장하고 중복 요청 방지 +- async/await 데코레이터 : 고차 함수로 데코레이터를 생성해 비동기 함수에 추가 기능 제공 + +> 자바스크립트 데코레이터 +> https://github.com/tc39/proposal-decorators +> 현재는 표준이 아니기 때문에 바벨로 트랜스파일하거나 타입스크립트를 사용해야 합니다. + +> 바벨로 데코레이터 사용하기 +> https://babeljs.io/docs/babel-plugin-proposal-decorators +> https://www.youtube.com/watch?v=9SuuHi7qk24 +> +> ```json +> // babel.config.json +> { +> "presents": ["@babel/preset-env"], +> "plugins": [["@babel/plugin-proposal-decorators", { "version": "2023-11" }]] +> } +> ``` + +> 타입스크립트에서 데코레이터 사용하기 +> https://devblogs.microsoft.com/typescript/announcing-typescript-5-0/#decorators +> https://blog.logrocket.com/practical-guide-typescript-decorators