자바스크립트에서 병렬 처리하기

 
Promise.all 처리하면 병렬처리가 된다. 이거만 궁금하는 분들만 있으니 일단 서두에 적어보았다.
 
자바스크립트 비동기 통신을 알기 전에 자바스크립트 통신은 왜 비동기일까? 그 답은 네트워크는 자바스크립트 인터프리터에서 동작하지 않기 때문이다. 브라우저에는 크게 총 7개의 구성 요소를 가진다. 나는 그것을 U URB(A)N DJ 라고 부른다. 유저 인터페이스, 유저 백엔드, 렌더링 엔진….
고로 네트워크와 자바스크립트 인터프리터는 독립적이다. 그렇기 때문에 따로 동작한다. 만약 하나로 되어 있다면, 자바스크립트는 단일 스레드이니 아주 느릿느릿한 맛을 보게 될 것이다.
 
Promise.all을 쓰는 방법은 아래와 같다.
Promise.all([function1(), function2()])
 
뭐지? 싶을건데, 사실 활용하려면 Promise에 대해서 알아야 한다. Promise는 3가지 상태 pending, fulfilled, rejected 상태를 가지며 then, catch, finally를 통해 후속 처리를 한다.
new Promise((resolve, rejected) => { setTimeout(() => { resolve("foo"); }, 300); }).then((res) => console.log(res));
자세한 설명이 필요하면 Promise 링크를 걸어두었으니 참고 바란다.
이제 이 Promise를 이용해서 비동기 처리를 만들어보자.
대충 짜보면 이렇다.
const test_a = () => new Promise((resolve, rejected) => { setTimeout(() => { resolve("a"); }, 3000); }).then((res) => console.log(res)); const test_b = () => new Promise((resolve, rejected) => { setTimeout(() => { resolve("b"); }, 4000); }).then((res) => console.log(res)); const test_c = () => new Promise((resolve, rejected) => { setTimeout(() => { resolve("c"); }, 5000); }).then((res) => console.log(res)); test_a(); test_b(); test_c();
이렇게 실행해도 병열처리가 된다. 왜냐면 실행하는 비동기 함수이기 때문에 블로킹이 되지 않고 한번에 처리되기 때문이다.
근데 이걸 바란게 아닐거라 생각한다.
근데 여기서 문제점이 있다면 후속처리를 후속처리 메서드(then, catch, finally)에서 처리해야한다. 머리가 복잡해졌으니까 수정해보자.
이 글을 본다면 여러분들은 이것보다 쉬운 async/await를 쓰고 있지 않을까 싶다.
// 서비스.js const test_a = () => new Promise((resolve, rejected) => { setTimeout(() => { resolve("a"); }, 3000); }).then((res) => res); const test_b = () => new Promise((resolve, rejected) => { setTimeout(() => { resolve("b"); }, 4000); }).then((res) => res); const test_c = () => new Promise((resolve, rejected) => { setTimeout(() => { resolve("c"); }, 5000); }).then((res) => res); // 호출하는 곳.js const test_async = async () => { console.time() const value_a = await test_a() const value_b = await test_b() const value_c = await test_c() console.timeEnd() }
default: 12018.111083984375 ms
이렇게 쓰면 문제는 우리가 쓰고 싶은 병열처리가 되지 않는다.
마음이 저며온다.
방금 Promise.all 배운 것 같으니 한번 써보자
// 서비스.js const test_a = () => new Promise((resolve, rejected) => { setTimeout(() => { resolve("a"); }, 3000); }).then((res) => res); const test_b = () => new Promise((resolve, rejected) => { setTimeout(() => { resolve("b"); }, 4000); }).then((res) => res); const test_c = () => new Promise((resolve, rejected) => { setTimeout(() => { resolve("c"); }, 5000); }).then((res) => res); const test_promise_all = async () => { console.time() const pomise = await Promise.all([test_a(), test_b(),test_c()]) console.timeEnd() console.log({pomise}) } test_promise_all()
default: 5006.612060546875 ms
병열처리가 되었다. 이제 내 제품에서 병열처리가 필요한 부분이 어딨는지 찾아보도록 한다.
이제 모아서 실행하면 된다. 근데 이거 넣는다고 드라마틱한 변화는 주기 어렵지만 도움이 되었으면 좋겠다.