Skip to content
Underbleu
GithubLinkedin

1-1. 인트로 - 합성, async:await, Promise

Functional programming1 min read

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

# 프로그래밍의 본질이란?

  • 문제들을 최대한 작게 쪼개서 해결하고 조합해 가는 과정이다
  • 코드사이의 공백, 코드마다 평가되는 시점에 무슨일이 일어나는지 정확히 알면
    1. 어떤 라이브러리나 프레임워크를 쓰게 되더라도 금방 사용법을 캐치할 수 있고, 굉장히 응용법을 다르게 할 수 있다
    2. 라이브러리의 코드를 디버깅하는 상황이 생겼을 때, 내 문제인지 라이브러리의 문제인지 정확히 파악하는 능력이 생겨 문제를 더 빨리 해결해나갈 수 있다

# 하스켈 표기법: 모든곳에 타입을 써준다

  • "f1은 a를 받아 b를 반환하는 함수다" 라는 표기를 함
    f1 :: Number a -> Number b
  • 하스켈은 인자를 하나밖에 넘기지 못한다 (currying)
  • 인자를 여러개를 한 번에 전달하는 방법? 튜플타입
    add(5, 5)를 -> add(5)(5)로 펴서 넣음

# async ...await

함수를 짤 때, 항상 비동기 코드를 염두하며 작성한다.
동기코드를 짤 때도 비동기가 될 상황을 염두함

1. await키워드

Promise객체가 fulfill되었을 때, 풀어서 결과값을 반환해주는 키워드

  • then 메소드를 사용할 때보다 복잡한 비동기 데이터 흐름을 아주 쉽게 표현할 수 있다는 장점
  • 하지만 await 역시도 내부적으로 then을 이용해 Promise를 푼다
1b = await Promise.resolve(10); // 10
2
3// -> await의 내부 동작 방식
4b = Promise.resolve(10).then(r => { // then으로 Promise를 풀어
5 b = r; //결과 값을 반환
6 return b;
7});

2. await는 "반드시 Promise를 리턴할거다" 라는 상황일 때만 사용하도록 권장

await가 받는 값이 Promise가 아닌경우, 이를 resolved Promise로 바꾼후 then으로 값을 풀어내는 await의 내부 동작 방식때문에 불필요한 시간이 소요된다

1// 1. 동기코드까지 await처리한 경우 -> 3번의 비동기
2b = await add10(a);
3b = await sub10(a);
4b = await sub10(a);
5
6add10(a).then(sub10).then(sub10);
7
8// 2. 동기, 비동기코드마다 다르게 처리한 경우 -> 1번의 비동기
9b = await add10(a);
10b = sub10(a);
11b = sub10(a);
12
13add10(10).then(function(a) {
14 sub10(sub10(a));
15});

3. 불필요한 비동기를 없애주자

log(): 상황에따라 동기-비동기식으로 돌아가는 함수 (=다형성 지원)

1function log(a) {
2 a instanceOf Promise ?
3 a.then(console.log) : console.log(a);
4}

# 공백하나까지 세밀하게 보는 언어 lisp

10년차까진 코드를 러프하게 봤다. 17년차인 지금은 코드의 공백 하나까지 세밀하게 본다

1(sub (add 5 3) 5) // -> 3
  • lisp코드: 모든게 리스트인 코드 - 공백까지 읽어야 해석되는 언어
  • lisp은 문장이 없는 언어, 자바스크립트는 문장도 있는 언어
  • 자바스크립트로 함수형 프로그래밍을 하려면, 필히 자바스크립트를 lisp처럼 읽을 수 있어야 한다
  • 함수형 프로그래밍을 안하더라도, 고급개발자가 되기 위해선 자바스크립트도 lisp처럼 읽을 수 있어야 한다
  • 자바스크립트는 scheme이라는 언어에서 많이 영향을 받음
    -> 한 줄, 한 줄이 값으로 평가될 수 있는 성질

Javascript Basic 추가 학습

# for...of / for...in

  • for...of - 이터러블의 value를 순회하기위해 사용
    (ex. array, string...)
  • for...in - 객체의 key를 이용하여 value를 순회할 때 사용
    -배열의 경우, length와 같은 프로퍼티도 출력될 수 있기 때문에 사용하지 않도록한다
1for (const v of [1,2,3]) console.log(v) // 1 2 3
2for (const k in [1,2,3]) console.log(k) // 0 1 2 length

# instanceof / isArray

  • isArray - object 자체가 Array인지를 체크. (ES5) 구형브라우저에서 작동 안함
  • instanceof - 프로토타입 체인에 Array.prototype이 있는지를 체크

만일 iframe을 사용하게 되면, 이는 새로운 scope를 형성하고 다른 실행컨택스트를 가지게된다. 그렇기 때문에 frame내에서 배열인지 판별하기 위해선 해당객체 자체를 평가하는 isArray를 사용해야한다

1Array.prototype !== window.frames[0].Array

# Parameter handling

  1. arguments
    인자를 유사배열 객체로 받을 수 있다 (화살표 함수에서 사용 불가)
  2. Rest 파라미터
    인자를 리스트 배열로 받을 수 있다
  • Spread Operator: 배열 또는 이터러블을 개별 요소로 분리

Spread 연산자를 사용한 매개변수 정의 (= Rest 파라미터)

1// 1. arguments
2!function () { console.log(arguments) } (1,2,3)
3// [1, 2, 3, callee: ƒ, Symbol(Symbol.iterator): ƒ]
4!function () { console.log(...arguments) } (1,2,3)
5// 1,2,3 -> spread operator
6
7// 2. rest
8!function (...rest) { console.log(rest) } (1,2,3)
9// [1,2,3]
10!function (...rest) { console.log(...rest) } (1,2,3)
11// 1,2,3 -> spread operator