2022-01-08
회사에서 어느 웹을 개발하던 도중에 성능 이슈가 좀 있어서
이를 어찌저찌 개선해보려다 친구놈한테 도움을 좀 청했었는데,
이 친구가 아주 기발한 기법을 알려줬다.
export const sleep = async milliseconds => await new Promise(resolve => setTimeout(resolve, milliseconds));
export const execAsync = async (...api) => {
let count = 0, results = {};
for (let i = 0; i < api.length; ++i)
(async () => {
try {
results[i] = await api[i]();
} catch (e) {e;} finally {
++count;
}
})();
while (count !== api.length)
await sleep(10);
return results;
};
내가 동시에 호출하고 싶은 API 함수들을 인자로 받고
각각이 끝날 때마다 카운팅해서 다 끝날 때까지 기다리는 로직이다.
마치 Java 스레드의 join
과 비슷하다.
저 코드에서 의문이 몇 가지 들 수 있는데,
일단 for
문에서 API를 호출하는 부분을 async-await로 된 즉시 실행 함수로 감싼 이유는
인자로 받는 API 함수 각각이 이미 Promise
를 리턴하는 것으로 전제로 하였고,
카운팅은 동기식 코드라 API 호출 후에 카운팅이 되어야하기 때문이다.
그리고 마지막에 while
문으로 모든 API 호출이 카운팅될 때까지 기다리는 데,
sleep
함수를 호출하지 않으면 이 while
문은 동기식 코드가 된다.