-
[Javascript] Section 17Frontend/Javascript 2023. 11. 10. 18:22
Javascript는 단일 스레드
일반적으로 더 오랜 시간이 소요되는 작업을 할 경우 해당 작업을 브라우저에서 오프로드 시킬 수 있다.
이벤트 루프
이벤트 루프는 비동기 코드를 사용하는 콜백 함수의 처리를 돕는다.
브라우저는 Javascript 코드 내부에서 특정 브라우저 API와 소통할 수 있는 다리 역할을 한다.
이벤트 루프는 메시지 대기열과 같이 브라우저의 빌트인 기능이다.
이 이벤트 루프는 Javascript 엔진이 아니라 Javascript의 호스트 환경 중 일부이다!!!
이벤트 루프의 역할은 엔진의 호출 스택을 대기 중인 메시지와 동기화한다.
이벤트 루프는 항시 실행 중인 상태로 스택이 비어있는 걸 보면 대기 중인 작업이 있는 지 확인하고 비어 있을 때에 이벤트 루프가 실행되어서 대기 중인 메시지나 작업 대상인 함수를 호출 스택으로 푸시한다.
-> 비동기 연산에서 일반적으로 사용하는 패턴!!!
비동기 함수 : 메시지 대기열로 보내 이벤트 루프가 최종적으로 이를 JS 호출 스택으로 전송하도록 푸시한다.
브라우저가 콜백 함수를 실행하려면 항상 메시지 대기열과 이벤트 루프에 대한 경로를 취해야 한다.
setTimeout의 시간은 무엇이든 보장된 시간이 아니라 최소 시간이다.(비동기 함수이기 때문!!!)
Promise
const setTimer = (duration) => { const promise = new Promise((resolve, reject) => { setTimeout(() => { }, duration); }); return promise; };promise는 생성자가 함수를 받는데 이 함수는 프로미스 API라서 이 프로미스가 생성될 때 바로 실행된다.
resolve 함수는 브라우저로부터 정확히는 Javascript 엔진으로부터 resolve 함수에 전달된다.
Promise chaining
반환하는게 꼭 promise일 필요는 없다. 문자열 같은 다른 데이터였다면 promise가 자동으로 감싸진다.
Promise chaining의 핵심은 단계별로 수행할 수 있다는 것
두번째 인자를 사용하든 catch 블록을 사용하든 관계없이 프로미스 체인의 catch 블록 이전 혹은 두번째 인자로 추가한 위치 이전에 발생하는 모든 오류나 거부를 잡아내도록 작동한다.
catch에서 일어나는 일은 이전의 모든 then 블록 중 하나가 거부하면 이전의 항목을 취소하거나 건너뛰는 것이다.
프로미스 상태
Pending : 프로미스가 작동중이며 then()이나 catch()가 실행되지 않는다.
Resolved : 프로미스가 해결되어 then()이 실행된다.
Rejected : 프로미스가 거절되어 catch()기 실행된다.
settled가 되면 특수 블록인 finally()로 최종 정리 작업을 수행할 수 있다.
async / await
함수에서만 쓸 수 있다.
async가 앞에 있으면 이 함수는 자동으로 프로미스를 반환한다.
async가 앞에 붙으면 이 전체 함수는 모든 내용을 하나의 큰 프로미스로 묶는다.
-> 그러면 여기서 then을 호출할 수 있는 효과가 있다.
여전히 then 블록을 사용하는 버전으로 바뀐다.
async await는 Javascript의 작동이나 실행방식을 바꾸는게 아니라 코드를 내부적으로 변환한다.
then 같은 일들이 내부적으로 진행되고 있다.
오류 처리는? try - catch 문으로 해결
단점
동일한 함수 내에서 동시에 작업을 실행할 수 없다.
await는 코드 실행을 일시 중지하는 것이 아니라 내부적으로 이 모든 단계들을 자체 then 블록으로 감싼다.
async await를 사용하기 시작하면 함수가 차례로 실행한다는 것을 인식하는것이 중요
Promise.race
데이터 반환이 가장 빠른 프로미스의 결과이다.
두 조건중 하나에만 관심이 있고 그 프로미스의 결과를 쓰고 다른 조건은 무시하려고 하는 경우 유용하다.
Promise.all
개별 프로미스가 해결한 모든 데이터의 조합을 반환한다.
Promise.all에 넣은 순서대로 각 프로미스에 의해 반한된 데이터를 가지는 배열이 결과이다.
프로미스 중 하나가 실패하면 다른 프로미스 역시 실행되지 않고 catch 블록으로 처리할 수 있는 오류가 뜬다.
Promise.allSettled
프로미스의 성공 여부 등등이 포함된 자세한 객체를 얻기 때문에 더 많은 유연성이 생긴다.
모든 프로미스가 끝날 때까지 기다리고 자세한 보고서를 얻을 수 있다.