Total
Search
1. async/await
•
비동기 상황을 보다 동기적인 코드로 다루기 위한 또하나의 방법
•
promise를 다루면서 평가시점을 제어하고 싶을 때 사용
•
async를 선언하면 Promiose 객체를 리턴함
•
async 함수의 결과값을 외부에서 사용하고 싶을 경우, .then을 통해 처리
function delay(a) {
return new Promise(resolve => setTimeout(() => resolve(a), 500));
}
async function f1() {
const a = await delay(10);
const b = await delay(5);
return a + b;
}
log(f1()); // Promise { <pending> }
log(await f1()); // 15
f1().then(log); // 15
JavaScript
복사
2. Q&A
2.1. Array.prototype.map이 있는데 왜 FxJS의 map 함수가 필요한지?
•
Array.prototype.map
◦
내부적으로 보조함수에서 promise가 리턴되거나 보조함수를 async 함수로 선언한다고 해서, map이 promise를 제어해주진 않음.
◦
안에서 비동기 상황을 제어할 수 없음
◦
결과 값을 변수에 저장하여 출력을 해보면 단지 promise가 담긴 배열에 불과함
◦
따라서, map 함수 자체가 promise 객체를 제어할 수 있어야함
•
FxJs.map
◦
map 함수 자체가 promise 객체를 제어 가능
import {map} from '../0_common/fx.js';
async function delayI(a) {
return new Promise(resolve => setTimeout(() => resolve(a), 100));
}
// array.prototype.map
async function f2() {
const list = [1, 2, 3, 4];
const temp = list.map(async a => await delayI(a * a));
console.log(temp); // [Promise, Promise, Promise, Promise]. Promise 객체들의 배열
const res = await temp;
console.log(res);
}
f2();
// 직접 구현한 map
async function f3() {
const list = [1, 2, 3, 4];
const temp = map(a => delayI(a * a), list);
console.log(temp); // Promise 객체. 배열 [1, 4, 9, 16]이 resolve될 준비가 되어있음
const res = await temp;
console.log(res); // [1, 4, 9, 16]
}
f3();
JavaScript
복사
2.2. 이제 비동기는 async/await로 제어할 수 있는데 왜 파이프라인이 필요한지?
•
파이프라인/iterable이 해결하려고 하는 문제와 async/await가 해결하려는 목적이 다르다.
•
async/await
◦
비동기 프로그래밍을 작성할때, 표현식으로 갇혀있는 (Promise.then.then) 과 같이 함수 체인이 아니라 문장형으로 다루기 위한 목적
◦
함수를 합성하는 게 아니라 반대로 풀어놓기 위한 목적
•
파이프라인/iterable
◦
비동기 프로그래밍을 위해서가 아니라, 명령형 프로그래밍을 하지 않고 안전하게 함수 합성을 하는 것
◦
함수를 합성하기 위한 목적
◦
비동기/동기 상황이냐가 관심이 있는 것이 아님
2.3. async/await와 파이프라인을 같이 사용하기도 하는지?
•
파이프라인으로 연산된 결과를 async/await를 통해 동기적으로 조합하여 사용 가능
2.4. 동기 상황에서 에러 핸들링은 어떻게 해야하는지?
•
여러가지 방법으로 에러 핸들링 가능 (디폴트 값을 넣는 등.. 방어로직 추가)
function f8(list) {
return (list || [])
.map(a => a + 10)
.filter(a => a % 2)
.slice(0, 2);
}
log(f7(null));
JavaScript
복사
•
가장 적절한 방법은 try catch문을 활용하여 오류 제어
2.5. 비동기 상황에서 에러 핸들링은 어떻게 해야하는지?
•
promise를 잘 제어할 수없는 파이프라인 코드는 에러핸들링이 잘 안됨
•
catch 문에 도달하기전에 오류가 raise 됨
•
async/await & .then().catch 등을 사용해도 핸들링 되지 않음
•
비동기에서 에러 핸들링을 처리하기는 어렵다.
async function f8(list) {
try {
return await list
.map(async a => await new Promise(resolve => {
dlfjaf;
}))
.filter(a => a % 2)
.slice(0, 2);
} catch (e) {
console.log(e);
return [];
}
}
f8(['0', '1', '2', '{']).then(a => console.log(a)).catch(e => console.log(e));
JavaScript
복사
2.6. 동기/비동기 에러핸들링에서의 파이프라인의 이점은?
•
try 안에서 비동기적으로 일어나는 함수가 catch에서 에러가 핸들링되기위해서는 try 내의 값이 promise.rejectd로 평가되어야함
•
지연 평가가 이루어지는 함수들 (L.map, L.filter) 들을 활용한다면 에러가 발생하지 않는 경우도 나올 수 있음
import {filter, go, map, take} from '../0_common/fx.js';
async function f9(list) {
try {
return await go(list,
map(a => new Promise(resolve => {
resolve(JSON.parse(a));
})),
filter(a => a % 2),
take(2));
} catch (e) {
console.log(e, '-----------------------');
return [];
}
}
f9(['0', '1', '2', '{']).then(a => console.log(a));
JavaScript
복사