Promise가 사용될때 await 키워드에서 코드 실행을 일시적으로 중지하고, 함수에서 반환된 Promise가 가능한 한번만 실행되도록 Javascript 런타임에 명령하는 방법을 실험으로 가정해봅니다:
// Not actual code. A thought experimentasyncfunctionfoo() {try {var val =awaitgetMeAPromise()console.log(val) } catch (err) {console.log('Error: ',err.message) }}
Promise가 수행을 계속한다면,
만약 await가 실행된다면, 값을 반환하며,
에러로 인하여 reject 된다면 catch에서 잡을 수 있도록 에러를 반환합니다.
이러한 수행은 갑자기 (신기할정도로) 비동기 프로그램을 동기프로그래밍처럼 쉽게 만들고 있습니다. 이러한 실험에는 세가지 사항이 필요합니다.
함수를 일시 중지하는 기능
함수안의 값을 출력하는 기능
함수내의 예외를 던질 수 있는 기능
이것은 꼭 제네레이터가 실행되는 원리 같습니다! 이러한 실험은 실제 발생할 수 있으며, Typescript / Javascript의 async/await에 대한 구현입니다. 실제로 async/await는 제네레이터를 사용하여 구현됩니다.
Generated JavaScript
이 원리를 꼭 이해할 필요는 없지만, 제네레이터를 읽었다면, 간단히 이해할 수 있습니다. foo 함수는 다음과 같이 간단히 정리할 수 있습니다.
wrapToReturnPromise는 제네레이터 함수를 사용하여 generator 객체를 반환받은 다음, generator.next()를 사용합니다. 만약 값이 promise 라면 then+catch하고 결과값을 generator.next(result)또는 generator.thorw(error) 로 호출해야 합니다. 그게 전부입니다.
Async Await Support in TypeScript
Async - Await 다음을 지원합니다. TypeScript since version 1.7. 비동기는 함수앞에는 async 키워드가 접두어로 붙습니다. await는 비동기 함수가 프로미스를 반환할때까지 실행을 일시 중단하고 반환된 프로미스 내부로부터 값을 반환받을 수 있습니다.
ES6 generators는 트랜스파일링을 통해 오직 es6를 지원합니다.
TypeScript 2.1added the capability to ES3 and ES5 run-times은 ES3 및 ES5 런타임에 제네레이터 기능을 추가했습니다. 즉, 사용중인 환경에 관계없이 자유롭게 활용이 가능합니다. Typescript2.1에서 async/await를 사용할 수 잇으며, Promise에 대한 polyfill을 전역으로 추가하여 다양한 브라우저에 대응할 수 있습니다.
예제를 보고 타입스크립트에서 async /await 표기법이 어떻게 작동하는지 알아봅니다.
functiondelay(milliseconds:number, count:number):Promise<number> {returnnewPromise<number>(resolve => {setTimeout(() => {resolve(count) }, milliseconds) })}// async function always returns a PromiseasyncfunctiondramaticWelcome():Promise<void> {console.log('Hello')for (let i =0; i <5; i++) {// await is converting Promise<number> into numberconstcount:number=awaitdelay(500, i)console.log(count) }console.log('World!')}dramaticWelcome()
참고: 두가지(ES6, ES5) 시나리오 모두에 대해서 런타임에 ECMAScript가 호환되는 Promise를 전역에 사용할 수 있는지 확인해야 합니다. 이 경우 Promise용 polyfill을 설정해야 할 수도 있습니다. 또한, tsc내 lib 플래그를 "dom", "es2015" 또는 "dom", "es2015.promise", "es5"와 같은 형식으로 설정하여 Typescript에 Promise가 포함되어 있음을 확인해야 합니다. 우리는 브라우저가 native 혹은 polyfill을 이용하여 프로미스를 지원하는지 볼수 있습니다. 여기를 클릭해주세요