Skip to content

Commit bddace0

Browse files
committed
5.4
1 parent 37b58db commit bddace0

File tree

1 file changed

+64
-0
lines changed
  • 05-asynchronous-control-flow-patterns-with-promises-and-async-await

1 file changed

+64
-0
lines changed
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import { TaskQueuePC } from './11-asyncawait-web-spider-v4/TaskQueuePC.js';
2+
3+
/**
4+
* ### 프라미스와 동시성 제한을 지원하는 Array.map() 의 비동기 병렬 버전을 구현하기
5+
* - 소개된 패턴은 사용해도 되지만, TaskQueue, TaskQueuePC 를 직접적으로 보완하지 않아야 함.
6+
*
7+
* @param {Iterable<any>} iterable 이터러블
8+
* @param {(item) => Promise<any>} callback 이터러블의 각 아이템을 입력으로 받고 프라미스와 간단한 값을 반환하는 콜백
9+
* @param {number} concurrency 이터러블에서 얼마나 많은 아이템이 벙렬로 처리될 수 있는지 정의하는 동시성
10+
*/
11+
async function mapAsync(iterable, callback, concurrency) {
12+
const result = [];
13+
const taskQueue = new TaskQueuePC(concurrency);
14+
15+
const arrayFromIter = [...iterable];
16+
17+
await arrayFromIter.reduce(async (acc, item) => {
18+
try {
19+
const value = await taskQueue.runTask(() => callback(item))
20+
await acc;
21+
return result.push(value);
22+
} catch (err) {
23+
throw err;
24+
}
25+
}, Promise.resolve());
26+
27+
return result;
28+
}
29+
30+
31+
32+
// ---------- TEST ----------------------------------------
33+
34+
const testIter = function* () {
35+
for (let i = 1; i <= 5; i++) {
36+
yield i;
37+
}
38+
};
39+
const callbackAsync = async ele => {
40+
return new Promise(resolve => {
41+
setTimeout(() => {
42+
resolve(ele * 2)
43+
}, ele%2 === 0 ? 100 : 200)
44+
})
45+
};
46+
47+
// 항상 [ 2, 4, 6, 8, 10 ] 로, callback 실행 순서와 관계없이 요소들의 순서는 보존되어야함.
48+
// concurrency 가 2 일떄 500ms, 3 일때 400ms, 4 일떄 300ms, 5일때 200ms 가 걸림.
49+
50+
console.time('mapAsync-2_expect: 500ms');
51+
console.log(await mapAsync(testIter(), callbackAsync, 2));
52+
console.timeEnd('mapAsync-2_expect: 500ms');
53+
54+
console.time('mapAsync-3_expect: 400ms');
55+
console.log(await mapAsync(testIter(), callbackAsync, 3));
56+
console.timeEnd('mapAsync-3_expect: 400ms');
57+
58+
console.time('mapAsync-4_expect: 300ms');
59+
console.log(await mapAsync(testIter(), callbackAsync, 4));
60+
console.timeEnd('mapAsync-4_expect: 300ms');
61+
62+
console.time('mapAsync-5_expect: 200ms');
63+
console.log(await mapAsync(testIter(), callbackAsync, 5));
64+
console.timeEnd('mapAsync-5_expect: 200ms');

0 commit comments

Comments
 (0)