callback - promise - async/await
발전된 자바스크립트 비동기 처리 문법
async 로 지정한 함수는 항상 promise 를 반환한다
명시적으로 promise를 반환할 수 있지만 그러지 않아도 결과는 같다
await 는 async 로 지정된 함수 내부에서만 동작하며
내부적으로 .then() 이 동작하는 것과 같은 것으로
async 로 지정된 함수 중간에 비동기 호출의 then() 을 변수처럼 다룰 수 있는 것이다
thenable 객체를 받을 수 있다
promise 객체와 마찬가지로 async await 문법은 thenable한 객체를 받을 수 있다
객체 내부에서 참조할 수 있는 then() 메소드가 있고, resolve, reject를 받아서 사용하도록 정의한다면 thenable한 객체로 평가하여 사용 가능하다
자바스크립트는 asyncronous / non-blocking 으로 동작한다
blocking/non-blocking 의 경우 한 작업이 다른 작업을 호출 시
바로 return 하는지에 따라 나뉜다
동기 비동기에 대한 이해는 좀 쉬운 편인데 blocking / non-blocking 과 함께라면
처음엔 지옥같은 경험을 할 수 있다..
non-blocking 이란 코드의 실행 완료 여부와 관계 없이 return 하여 다른 코드의 실행을 막지 않는다는 뜻이다
blocking 은 완료 시 까지 return을 하지 않고 막는다는 뜻..
코드의 실행이 다른 코드의 실행을 막을 수 있다는 것은
제어권이라는 어려운 단어로 표현할 수 있다
자바스크립트의 경우 싱글 스레드이기 때문에 하나의 작업 흐름이 있고
하나의 제어권이 있다고 생각할 수 있을 것 같다
이 제어권을 일반 함수에서는 순차적으로 가져가서 사용하고 반납하는데
blocking의 경우 함수의 실행이 완료될 때 까지 반납을 하지 않고 다른 코드의 실행을 막는다
non-blocking의 경우 실행 여부와 관계 없이 반납하여 원래의 작업 흐름을 바로 이어갈 수 있다
동기의 경우 완료 시점에 대해 기다리기 때문에 blocking으로 제어권을 바로 반환하지 않아도
행동에 대한 예측이 쉽다
non-blocking을 하게 되면 제어권을 바로 반납받기 때문에 기존의 작업을 수행하면서
제어권을 가져갔던 함수의 완료 여부에 대해 지속적으로 확인한다
비동기의 경우 호출한 함수가 호출된 함수의 완료 여부를 기다리진 않지만 blocking을 한다면 제어권을 돌려받지 못하여 동기 처럼 동작한다
non-blocking을 한다면 제어권을 바로 돌려받기 때문에 기존의 완료 여부를 기다리지 않고 기존의 동작을 수행하는 것으로 예측이 쉽다
대신 비동기 함수는 완료 시점에 콜백을 반환하여 task queue로 보내고 이벤트 루프를 통해 기존 실행 흐름인 call stack 이 비어있을 때 콜백 함수를 call stack으로 보내 실행하는 것으로 작업의 완료 여부를 확인할 수 있다
https://steady-coding.tistory.com/531
async / await 는 block 으로 이해하는 경우가 많다
await 가 순서를 보장하기 때문이다
async 로 지정된 함수 내부에서
await 끼리 blocking을 하는 것 처럼 보이게 동작하기 때문이다
하지만 await 는 .then() 을 변수 내부에 저장하여 보류했다가 순서대로 실행할 뿐이기 때문에
blocking 을 한다고 보기에는 어렵다
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function
async await 문법은
async 로 지정된 함수 내부에서만 await 으로 담은 비동기 호출이
동기 처럼 순서를 보장하는 것일 뿐 blocking 이라고 볼 수 없다
async 로 작성된 함수가 자신을 호출한 기존 작업 흐름에 대해 제어권을 거의 바로 받납하기 때문이다
async function foo() {
console.log("hi");
return 1;
}
async function bar() {
const result = await foo();
console.log(result);
}
bar();
console.log("lo");
hi - lo - 1 순서로 실행 결과를 얻을 수 있다
만약 async await 가 blocking 으로 동작한다면
hi - 1 - lo 의 순서의 결과를 반환해야 한다