Skip to content
Underbleu
GithubLinkedin

2-4. 컬렉션 중심 프로그래밍 - 명령형으로 map, filter의 Promise 다형성 구현, Promise의 규칙

Functional programming1 min read

프로그래머스에서 진행한 유인동님의 ES6로 알아보는 동시성 & 함수형 프로그래밍 강의를 들으며 정리한 내용입니다.

1. map, filter를 명령형으로 짜보기

1function map(f, coll) {
2 const res = [];
3 const iter = coll[Symbol.iterator]();
4 return function recur() {
5 for(const a of iter) {
6 const b = f(a);
7 if (b instanceof Promise) {
8 return b.then(function(b) {
9 res.push(b);
10 return recur();
11 })
12 } else {
13 res.push(b);
14 }
15 }
16 return res;
17 } ();
18}
19
20function filter(f, coll) {
21 const res = [];
22 const iter = coll[Symbol.iterator]();
23 return function recur() {
24 for(const a of iter) {
25 const b = f(a);
26 if (b instanceof Promise) {
27 return b.then(function(b) {
28 if(b) res.push(a);
29 return recur();
30 })
31 } else {
32 if(b) res.push(a);
33 }
34 }
35 return res;
36 } ();
37}
38
39map(a => Promise.resolve(a + 100), [1,2,3]).then(console.log) // [101,102,103]
40filter(a => Promise.resolve(a > 2), [1,2,3]).then(console.log) // [3]

# 한 번의 then으로 중첩된 프로미스 값을 꺼낼 수 있다 (중요)

  • then은 프로미스가 모두 완료되길 기다렸다가 값을 꺼낸다
  • then()안에 아무리 많은 프로미스가 있더라도, 이들이 모두 완료되길 기다렸다가 값을 꺼낸다
  • setTimeout(), setInterval() 비동기 함수를 걸어도 then은 동작한다
1const then2 = (f, a) => a instanceof Promise ? a.then(f) : f(a);
2
3Promise.resolve(10)
4 .then(a => a + 10)
5 .then(a => a + 10)
6 .then(a => a + 10)
7 .then(console.log) // 40
8
9then2(console.log, Promise.resolve(10)
10 .then(a => a + 10)
11 .then(a => a + 10)
12 .then(a => a + 10)
13 .then(console.log) // 40
14)
15
16new Promise(function(resolve) {
17 resolve(Promise.resolve(Promise.resolve(Promise.resolve(10))))
18}).then(a => a + 100)
19 .then(console.log) // 110
20
21
22new Promise(function(resolve) {
23 resolve(new Promise(function(resolve) {
24 setTimeout(function() {
25 resolve(10)
26 }, 1000)
27 }))
28}).then(a => a + 1000)
29 .then(console.log) // 1010
30
31
32then2(console.log, new Promise(function(resolve) {
33 resolve(new Promise(function(resolve) {
34 setTimeout(function() {
35 resolve(10)
36 }, 1000)
37 }))
38}).then(a => a + 1000)) // 1010
  • 프로미스를 기반으로 돌아가는 async...await
  • 프로미스는 일급객체로서 여러함수의 인자로 전달 될 수 있고, then으로 꺼내 쓸 수 있다
    -> 함수형 프로그래밍에서의 비동기를 관리하는 모나드 같음

Promise를 얼마나 아느냐가, 자바스크립트에서 동시성을 얼마나 잘 다루는지의 거의 전부라 할 수 있다


# 앞으로 reduce를 활용한 map과 filter를 짤 것

앞으로 이런 복잡한 명령형 코드를 만들어놓은 reduce함수를 활용해 간편하게 짤거다. Test Case를 다 통과하는 추상화된 함수 reduce()를 하나 만들어 놓고 나면

  • 보조함수를 붙여서 애플리케이션에 필요한 기능별 함수들을 만들 수 있을 뿐만 아니라
  • 동기/비동기를 모두 하나의 함수로 처리할 수 있다

이러한 추상도 높은 함수세트를 제작해놓은 이후엔 두가지 규칙만 지키면 된다

  1. await가 코드에 나오지 않도록 짜야하고
  2. 모든 함수가 연속적으로, 중첩적으로 실행되게 하면된다