# Javascript Async return Promise For await
## # async function
#### Reference
- [https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/async_function](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/async_function)
#### async function
- async function 선언은 AsyncFunction객체를 반환하는 하나의 비동기 함수를 정의한다.
- 또한 async function expression을 사용해서 async function을 선언할 수도 있다.
```javascript
async function name([param[, param[, ... param]]]) {
statements
}
```
- asnyc/await 는 비동기 코드를 작성하는 새로운 방법이다.
이전에는 비동기코드를 작성하기 위해 callback이나 promises를 사용해야 했다.
- async 함수에는 await식이 포함될 수 있습니다.
이 식은 async 함수의 실행을 일시 중지하고 전달 된
Promise의 해결을 기다린 다음 async 함수의 실행을 다시 시작하고 완료후 값을 반환합니다.
- async 함수내에 await가 유효합니다.
- async 함수의 본문 외부에서 사용하면 SyntaxError가 발생합니다.
#### Syntax
async function name([param[, param[, ... param]]]) {
statements
}
- 매개변수
- name : 함수의 이름.
- param : 함수에게 전달되기 위한 인자의 이름.
- statements : 함수본문을 구성하는 내용.
- 반환 값
- Promise
async 함수에 의해 반환 된 값으로 해결되거나 async함수 내에서 발생하는 캐치되지 않는 예외로 거부되는 값.
#### 목적
- async/await함수의 목적은
사용하는 여러 promise의 동작을 동기스럽게 사용할 수 있게 하고,
어떠한 동작을 여러 promise의 그룹에서 간단하게 동작하게 하는 것이다.
- promise가 구조화된 callback과 유사한 것 처럼
async/await또한 제네레이터(generator)와 프로미스(promise)를 묶는것과 유사하다.
ex)
```javascript
function resolveAfter2Seconds(x) {
return new Promise(resolve => {
setTimeout(() => {
resolve(x);
}, 2000);
});
}
async function add1(x) {
const a = await resolveAfter2Seconds(20);
const b = await resolveAfter2Seconds(30);
return x + a + b;
}
add1(10).then(v => {
console.log(v); // prints 60 after 4 seconds.
});
async function add2(x) {
const p_a = resolveAfter2Seconds(20);
const p_b = resolveAfter2Seconds(30);
return x + await p_a + await p_b;
}
add2(10).then(v => {
console.log(v); // prints 60 after 2 seconds.
});
```
#### await와 promise.all을 혼동하지 마세요
- add1에서 첫 번째 await는 2 초이고 두 번째 await는 다시 2 초입니다.
두 번째 타이머는 첫 번째 타이머가 완료될 때까지 생성되지 않습니다.
- add2에서는 두 타이머가 모두 생성 된 다음 두 타이머가 await됩니다.
이렇게하면 타이머가 동시에 실행되기 때문에 4 초가 아닌 2 초가 지나면 해결됩니다.
- 그러나 두 await 호출은 모두 병렬로 진행되는 것이 아니라 연속적인 호출로 실행됩니다.
이는 Promise.all의 자동 응용 프로그램이 아닙니다.
두 개 이상의 promise를 동시에 await시키고 싶다면 Promise.all을 사용해야합니다.
#### async함수를 사용한 promise chain 재작성
- Promise 를 반환하는 API는 promise chain을 만들며 여러 파트의 함수로 나뉜다.
아래 코드를 보자.
```javascript
function getProcessedData(url) {
return downloadData(url) // returns a promise
.catch(e => {
return downloadFallbackData(url) // returns a promise
})
.then(v => {
return processDataInWorker(v); // returns a promise
});
}
```
- 위의 코드는 하나의 async함수로 아래와 같이 쓰여질 수도 있다.
```javascript
async function getProcessedData(url) {
let v;
try {
v = await downloadData(url);
} catch (e) {
v = await downloadFallbackData(url);
}
return processDataInWorker(v);
}
```
- 위 예제에서는 return 구문에 await 구문이 없다는 것에 주목하자. 이는 async function의 반환값이 암묵적으로 Promise.resolve로 감싸지기 때문이다.
## # async function expression
- [https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/async_function](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/async_function)
- async function 키워드는 async 함수를 정의하는데 사용하는 표현식입니다.
#### Syntax
async function [name]([param1[, param2[, ..., paramN]]]) { statements }
- Parameters
- name : 함수 이름. 함수의 이름은 오직 함수 몸체에서 지역적으로 사용되며,
함수 이름을 선언하지 않으면 익명함수로 사용된다.
- paramN : 함수에 전달되는 매개변수.
- statements : 함수를 구성하는 구문.
#### Description
async function 표현식은 async function 선언 문법과 거의 동일합니다.
async function 표현식과 async function 선언문의 주요 차이점은 익명함수로써의 사용 여부로,
async function 표현식은 함수 이름을 생략하면 익명함수를 만듭니다.
async function 표현식은 IIFE(즉시실행함수)로 사용할 수 있습니다. functions문서를 참고하세요.
#### Examples
```javascript
//Simple example
function resolveAfter2Seconds(x) {
return new Promise(resolve => {
setTimeout(() => {
resolve(x);
}, 2000);
});
};
var add = async function(x) { // async function 표현식을 변수에 할당
var a = await resolveAfter2Seconds(20);
var b = await resolveAfter2Seconds(30);
return x + a + b;
};
add(10).then(v => {
console.log(v); // 4초 뒤에 60 출력
});
(async function(x) { // async function 표현식을 IIFE로 사용
var p_a = resolveAfter2Seconds(20);
var p_b = resolveAfter2Seconds(30);
return x + await p_a + await p_b;
})(10).then(v => {
console.log(v); // 2초 뒤에 60 출력
});
```
## # AsyncFunction
- [https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/AsyncFunction](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/AsyncFunction)
- AsyncFunction 생성자는 새로운 async function 객체를 만든다.
- 자바스크립트에서 모든 비동기 함수는 사실상 AsyncFunction 객체이다.
- AsyncFunction이 전역변수가 아님에 주의하는게 좋다. 다음의 코드를 살펴보면서 한번 알아보자.
- >> Object.getPrototypeOf(async function(){}).constructor
#### Syntax
new AsyncFunction([arg1[, arg2[, ...argN]],] functionBody)
- Parameters
- arg1, arg2, ... argN
- 함수에 따라 그 인수들이 정해짐에 알아야한다.
- 이러한 인수들은 "x","theValue",or"a,b"와 같은 자바스크립트 식별자나 콤마로 구분된 문자열과 같은게 사용되어야 한다.
- functionBody
함수 정의로 구성된 자바 스크립트 설명서를 포함하는 문자열이다.
#### Description
- AsyncFunction 생성자를 통해 만들어진async function 객체는 함수가 만들어질때 분석된다.
- 코드가 실행되지 않을 때도 작동하기 때문에
async function expression 으로 비동기함수를 정의하고 해당 코드에서 호출할 때보다 비효율적이다.
- 모든 인수들은 순서대로 생성된 함수의 파라미터의 식별자로서 함수안에서 다뤄진다.
- Note: async functions created with the AsyncFunction constructor do not create closures to their creation contexts;
- they are always created in the global scope. When running them,
- they will only be able to access their own local variables and global ones,
- not the ones from the scope in which the AsyncFunction constructor was called.
- This is different from using eval with code for a async function expression.
- AsyncFunction 생성자를 새로운 연산자없이 함수로서 호출하는 것은 새로운 생성자를 호출하는 것과 같다.
#### Properties
- AsyncFunction.length : AsyncFunction 생성자의 길이 속성의 값은 1이다.
- AsyncFunction.prototype : 모든 비동기 객체에 속성을 추가하게끔 해준다.
#### AsyncFunction prototype object
- Properties
- AsyncFunction.constructor : The initial value is AsyncFunction.
- AsyncFunction.prototype[@@toStringTag] : Returns "AsyncFunction".
#### AsyncFunction 인스턴스
- AsyncFunction AsyncFunction.prototype으로 부터의 메소드와 속성을 상속받는다.
- 모든 생성자와 마찬가지로, 누가나 생성자의 프로토타임 객체를 AsyncFunction 인스턴스로 만들기 위해 변경할 수 있다.
#### Examples
- AsyncFunction 생성자를 통한 비동기 함수 제작
```javascript
function resolveAfter2Seconds(x) {
return new Promise(resolve => {
setTimeout(() => {
resolve(x);
}, 2000);
});
}
var AsyncFunction = Object.getPrototypeOf(async function(){}).constructor
var a = new AsyncFunction('a',
'b',
'return await resolveAfter2Seconds(a) + await resolveAfter2Seconds(b);');
a(10, 20).then(v => {
console.log(v); // prints 30 after 4 seconds
});
```
```javascript
// wait ms milliseconds
function wait(ms) {
return new Promise(r => setTimeout(r, ms));
}
async function hello() {
await wait(1500);
return 'world';
}
hello()
.then(function(r,j){
console.info(r,j);
})
.catch(function(e){
console.info(e);
});
==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ====
// wait ms milliseconds
function wait(ms) {
return new Promise(r => setTimeout(r, ms));
}
async function foo() {
// await wait(500);
throw Error('bar');
}
async function foo() {
// await wait(500);
throw {"aError":"aError"}
}
foo()
.then(function(r,j){
console.info(r,j);
})
.catch(function(e){
console.info(e);
});
```
'web > javascript' 카테고리의 다른 글
bind click event loop index (0) | 2019.07.12 |
---|---|
Javascript Async, Await 심화 (0) | 2019.07.12 |
ECMA6 (0) | 2019.01.30 |
Javascript Async, Await 심화 (0) | 2019.01.30 |
Javascript arrow function expression (0) | 2019.01.30 |
댓글