Created by 손찬욱
어려운 용어도 많아서 쓰기도 어려운데.
배열 데이터도 입력값으로
함수 반환값 도 입력값으로
키보드를 누르는 것도 입력값으로
마우스를 움직이는 것도 입력값으로
원격지의 데이터도 입력값으로
DB 데이터도 입력값으로
...
어떤 것은 동기 (Synchronous)
어떤 것은 비동기 (Asynchronous)
어떤 것은 함수 호출(Call)
어떤 것은 이벤트(Event)
어떤 것은 Callback
어떤 것은 Promise
시간을 인덱스로 둔 컬렉션
어떤 것은 동기 (Synchronous)
어떤 것은 비동기 (Asynchronous)
어떤 것은 함수 호출(Call)
어떤 것은 이벤트(Event)
어떤 것은 Callback
어떤 것은 Promise
의존관계가 있는 상태머신에게
변경된 상태 정보를 어떻게 전달하지?
데이터 흐름과 상태 변화 전파에 중점을 둔 프로그램 패러다임이다. 사용되는 프로그래밍 언어에서 데이터 흐름을 쉽게 표현할 수 있어야하며 기본 실행 모델이 변경 사항을 데이터 흐름을 통해 자동으로 전파한다는 것을 의미한다.
Observer pattern
Subject의 변경사항이 생기면 자동으로
Observer의 update를 호출한다. (Loosely Coupling)
next, error, complete의 3가지 상태를 전달받음
데이터를 받은 후에 받은 데이터를 가공한다.
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if(xhr.readyState == 4 && xhr.status == 200) {
const jsonData = JSON.parse(xhr.responseText);
document.getElementById("users").innerHTML =
process(jsonData);
}
};
xhr.open("GET", "https://swapi.co/api/people/?format=json");
xhr.send();
process 함수
// 데이터를 처리하는 함수
function process(people) {
const html = [];
for (const user of people.results) {
if (/male|female/.test(user.gender)) {
let broca;
let bmi;
if (user.gender == "male") {
broca = (user.height - 100 * 0.9).toFixed(2);
bmi = (user.height / 100 * user.height / 100 * 22).toFixed(2);
} else {
broca = (user.height - 100 * 0.9).toFixed(2);
bmi = (user.height / 100 * user.height / 100 * 21).toFixed(2);
}
const obesityUsingBroca = ((user.mass - broca) / broca * 100).toFixed(2);
const obesityUsingBmi = ((user.mass - bmi) / bmi * 100).toFixed(2);
html.push(`<li class='card'>
<dl>
<dt>${user.name} <i class="fa fa-${user.gender}"></i></dt>
<dd><span>키 : </span><span>${user.height} cm</span></dd>
<dd><span>몸무게: </span><span>${user.mass} kg</span></dd>
<dd><span>BROCA 표준체중 : </span><span>${broca} kg</span></dd>
<dd><span>BROCA 비만도 : ${obesityUsingBroca}</span></dd>
<dd><span>BMI 표준체중 : </span><span>${bmi} kg</span></dd>
<dd><span>BMI 비만도 : ${obesityUsingBmi}</span></dd>
</dl>
</li>`);
}
}
return html.join("");
}
조건문, 반복문 덩어리로 구성됨
if (A) {
// 이럴 경우에는..
for(let i = 0; i <len; i++) {
// 실제 로직A는 여기서...
}
} else {
// 저럴 경우에는
for(let i = 0; i <len; i++) {
// 실제 로직B는 여기서...
// 여기도 if문이...
if (B) {
// ...
}
}
// ...
}
조건문은 코드의 흐름을 분리하고
반복문은 코드의 가독성을 떨어뜨림.
주관심사인 비즈니스 로직은 코드에 파묻힘
다른 함수를 인자로 받거나 그 결과로 함수를 반환하는 함수.
고차 함수는 변경되는 주요 부분을 함수로 제공함으로서
동일한 패턴 내에 존재하는 문제를 손쉽게 해결할 수 있는 고급 프로그래밍 기법이다.
filter, map, reduce, ... 와 같은 고차함수의 operator를 제공
Rx.Observable
.ajax("https://swapi.co/api/people/?format=json")
.filter(user => /male|female/.test(user.gender))
.map(user => Object.assign(
user,
logic(user.height, user.mass, user.gender)
))
.reduce((acc, user) => {
acc.push(makeHtml(user));
return acc;
}, [])
.subscribe(v => {
document.getElementById("users").innerHTML = v;
});
내가 실행한 로직이 나의 의도와 상관없게
외부에 영향을 미친다면?
Side Effect
함수에 드러나지 않은 입력값을 부원인(Side Cause)라고 하고 이로 인해 발생한 결과를 부작용(Side Effect)
function getCurrentValue(value) {
return processAt(value, new Date());
}
function get(objectValue) {
objectValue.newProp = "바꿨지롱 모르겠지?";
// bla bla
return objectValue;
}
모든 입력값을 명시적으로 나타낸다.
function getCurrentValue(value, time) {
return processAt(value, time);
}
Immutable 데이터를 사용한다.
function get(objectValue) {
const obj = Object.assign({}, objectValue);
obj.newProp = "바꿨으면 데이터 객체의 레퍼런스를 바꾸야지";
return obj;
}
함수형 프로그래밍은 자료 처리를 수학적 함수의 계산으로 취급하고 상태 변경과 가변 데이터를 피하려는 프로그래밍 패러다임의 하나이다.
Functional Programming은 순수함수를 지향한다.
Observable 자체가 Immutable.
RxJS에서는 다루는 중요 개념은 다음과 같다.
하지만 4대 천왕만 알면 된다.
다른거는 심화과정
데이터를 변경. 추출. 합침. 분리
const observer = {
next: x => console.log("Observer가 Observable로부터 받은 데이터: " + x),
error: err => console.error("Observer가 Observable로부터 받은 에러 데이터: " + err),
complete: () => console.log("Observer가 Observable로부터 종료 되었다는 알림을 받은 경우"),
};
subscription.unsubscribe();
하지만,
여기에서 이야기한 자세한 설명은
다음 사이트에서 보실수 있습니다.
https://github.com/sculove/rxjs-book https://sculove.github.com