[Javascript] 비동기 자바스크립트

[원본 링크]

근래 들어서 자바스크립트 비동기 처리를 위한 기능이 몇개 추가되었다.

자바스크립트는 기본적으로 싱글 스레드에서 단순하게 작동하지만, 멀티스레딩처럼 작동하는 예외가 몇개 있다. ('처럼'이지 진짜는 아니다.)

setTimeout과 같은 함수가 그것이다.
이건 핸들러와 밀리초를 받고, 밀리초가 지났을때 핸들러 함수를 호출한다.

비동기적으로 작동하기 때문에 아래와 같은 코드도 image

image a가 변경된 후에 호출될 수 있다는 것이다.
그렇다면 핸들러가 호출된 후에 a가 변경되게 하려면 어떻게 해야할까?


첫번째 방법: 손으로 한땀한땀 짠다.
콜백을 받는 함수로 분리하고 setTimeout의 핸들러 마지막부분에 해당 콜백을 호출하면 된다.
조잡하긴 하지만 되긴 된다. image

image


Promise 객체 사****용(ES6)
비동기 처리식을 Promise 객체를 통해서 사용하는 방법도 있다.
ES6부터 지원되는 기능이다.

Promise 객체는 2개의 인자를 갖는 핸들러를 하나 받는다.
그리고 핸들러에서는 비동기 동작이 성공적으로 끝났을 경우, 첫번째 인자로 받는 resolve를 호출한다.
이러면 프로미스의 .then()에 전달한 핸들러가 호출된다. image

image

반대로, 뭔가 실패했을 경우엔 두번째 인자인 reject를 호출한다.
이럴때는 catch로 전달한 핸들러가 호출되는데, 만약 catch 설정된 핸들러가 없다면 에러가 터진다. image

image

resolve나 reject를 호출할때 인자를 전달할 수도 있다. 이런식으로, then과 catch 인자로 전달된다. image

image

setTimeout을 Promise 방식으로 개조하면 대충 이렇게 되겠다. image

image


**async/await(ES8) **
근데 프로미스만으로도 표현이 좀 부족할 수 있다.
위의 예시들은 간단해서 별로 느껴지진 않겠지만, 비동기표현이 중첩되면 코드가 몹시 난잡해진다.

async와 await는 그런 코드를 좀 간결하게 만들고자 고안되었다.

일단 await는 프로미스 객체의 결과값을 받길 기다리며 블럭시킨다. 해당 비동기 작업이 끝날때까지 기다리는 것이다.
await 구문은 async 함수 내에만 존재할 수 있다.

그리고 async 함수는 자동으로 결과값을 프로미스로 반환한다.

아래는 foo->bar->boom 순서대로 비동기 작업을 수행하는 간단한 코드다. image

image

아래 코드는 setTimeout에 async/await를 적용한 것이다. image

image 잘 돈다.


참조
https://blueshw.github.io/2018/02/27/async-await/
https://joshua1988.github.io/web-development/javascript/promise-for-beginners/
https://stackoverflow.com/questions/39538473/using-settimeout-on-promise-chain