๋ณธ๋ฌธ์œผ๋กœ ๊ฑด๋„ˆ๋›ฐ๊ธฐ

๐ŸŒˆ Chapter 8: ๋น„๋™๊ธฐ ์ด๋ฒคํŠธ์™€ ๋ฐ์ดํ„ฐ๋ฅผ ๊ด€๋ฆฌ

๐Ÿ“š ๊ณจ์นซ๋ฉ์ด ๋น„๋™๊ธฐ ์ฝ”๋“œโ€‹

  • ๋น„์ฐจ๋‹จ ๋น„๋™๊ธฐ ํ˜ธ์ถœ ์ฝ”๋“œ๋ฅผ ๊ตฌํ˜„ํ•˜์—ฌ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š”๋ฐ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ๋ฐœ๋ชฉ์„ ์žก๋Š”๋‹ค.
    1. ํ•จ์ˆ˜ ๊ฐ„์— ์ผ์‹œ์  ์˜์กด ๊ด€๊ณ„๊ฐ€ ํ˜•์„ฑ
    2. ์–ด์ฉ” ์ˆ˜ ์—†์ด ์ฝœ๋ฐฑ ํ”ผ๋ผ๋ฏธ๋“œ ๋Šช์— ๋น ์ง
    3. ๋™๊ธฐ/๋น„๋™๊ธฐ ์ฝ”๋“œ์˜ ํ˜ธํ™˜๋˜์ง€ ์•Š๋Š” ์กฐํ•ฉ

๐ŸŽˆ ํ•จ์ˆ˜ ๊ฐ„์— ์ผ์‹œ์  ์˜์กด ๊ด€๊ณ„๊ฐ€ ํ˜•์„ฑโ€‹

  • ์ผ์‹œ์  ๊ฒฐํ•ฉ(temporal coupling) (์ผ์‹œ์  ์‘์ง‘ temporal cohesion)์€ ์–ด๋–ค ํ•จ์ˆ˜๋ฅผ ๋…ผ๋ฆฌ์ ์œผ๋กœ ๋ฌถ์–ด ์‹คํ–‰ํ•  ๋•Œ ๋ฐœ์ƒํ•œ๋‹ค.
  • ๋ฐ์ดํ„ฐ๊ฐ€ ๋„์ฐฉํ•  ๋•Œ๊นŒ์ง€, ๋˜๋Š” ๋‹ค๋ฅธ ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋  ๋•Œ๊นŒ์ง€ ์–ด๋–ค ํ•จ์ˆ˜๊ฐ€ ๊ธฐ๋‹ค๋ ค์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ์ด๋‹ค.
  • ๋ฐ์ดํ„ฐ๋“  ์‹œ๊ฐ„์ด๋“  ์–ด๋Š ์ชฝ์— ์˜์ง€ํ•˜๋Š” ์ˆœ๊ฐ„๋ถ€ํ„ฐ ๋ถ€์ˆ˜ํšจ๊ณผ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.
  • ์›๊ฒฉ IO ์ž‘์—…์€ ๋‚˜๋จธ์ง€ ๋‹ค๋ฅธ ์ฝ”๋“œ์— ๋น„ํ•ด ์†๋„๊ฐ€ ๋Š๋ฆด ์ˆ˜๋ฐ–์— ์—†์œผ๋ฏ€๋กœ ๋ฐ์ดํ„ฐ ์š”์ฒญ ํ›„ ๋‹ค์‹œ ๋Œ์•„์˜ฌ ๋•Œ๊นŒ์ง€ '๋Œ€๊ธฐ' ๊ฐ€๋Šฅํ•œ ๋น„์ฐจ๋‹จ ํ”„๋กœ์„ธ์Šค์—๊ฒŒ ์ฒ˜๋ฆฌ๋ฅผ ์œ„์ž„ํ•œ๋‹ค.
  • ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ ๋งŽ์ด ์“ฐ์ด์ง€๋งŒ, ๋Œ€๋Ÿ‰ ๋ฐ์ดํ„ฐ๋ฅผ ์ˆœ์ฐจ์ ์œผ๋กœ ๋กœ๋“œํ•  ๊ฒฝ์šฐ ํ™•์žฅํ•˜๊ธฐ๊ฐ€ ์–ด๋ ต๊ณ  ๊ฒฐ๊ตญ ์ฝœ๋ฐฑ ํ”ผ๋ผ๋ฏธ๋“œ์— ๋น ์ง€๊ฒŒ ๋œ๋‹ค.

๐ŸŽˆ ์ฝœ๋ฐฑ ํ”ผ๋ผ๋ฏธ๋“œ์˜ ๋Šช์— ๋น ์งโ€‹

  • ์ฝœ๋ฐฑ์˜ ์ฃผ์šฉ๋„๋Š” ์ฒ˜๋ฆฌ ์‹œ๊ฐ„์ด ์˜ค๋ž˜ ๊ฑธ๋ฆฌ๋Š” ํ”„๋กœ์„ธ์Šค๋ฅผ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๋„์ค‘ UI๋ฅผ ์ฐจ๋‹จํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ด๋‹ค.
  • ์ฝœ๋ฐฑ์„ ๋ฐ›๋Š” ํ•จ์ˆ˜๋Š” ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋Œ€์‹  **์ œ์–ด์˜ ์—ญ์ „(inversion of control)**์„ ์‹ค์ฒœํ•œ๋‹ค.
var students = null;
getJSON('/students',
function(students) {
showStudents(students);
},
function(error) {
console.log(error.message);
},
);
  • ๊ทธ๋Ÿฌ๋‚˜ ์ด๋Ÿฐ ์‹์˜ ์ œ์–ด์˜ ์—ญ์ „ ๊ตฌ์กฐ๋Š” ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ์„ค๊ณ„ ์‚ฌ์ƒ๊ณผ ์ •๋ฉด์œผ๋กœ ๋ฐฐ์น˜๋œ๋‹ค.
  • ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋žจ์˜ ํ•จ์ˆ˜๋Š” ์„œ๋กœ ๋…๋ฆฝ์ ์ด๋ฉฐ, ๊ฐ’์„ ํ˜ธ์ถœ์ž์— ์ฆ‰์‹œ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•œ๋‹ค.

๐ŸŽˆ ์—ฐ์†์ฒด ์ „๋‹ฌ ์Šคํƒ€์ผโ€‹

  • ์ค‘์ฒฉ๋œ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋Š” ์ฝ๊ธฐ๋„ ์–ด๋ ต์ง€๋งŒ, ์ž๊ธฐ ์Šค์ฝ”ํ”„ ๋ฐ ์ž์‹ ์ด ์ค‘์ฒฉ๋œ ํ•จ์ˆ˜์˜ ๋ณ€์ˆ˜ ์Šค์ฝ”ํ”„๋ฅผ ๊ฐ์‹ผ ํด๋กœ์ €๋ฅผ ๋งŒ๋“ ๋‹ค.
  • ์–ด๋–ค ํ•จ์ˆ˜๋ฅผ ๋‹ค๋ฅธ ํ•จ์ˆ˜์— ์ค‘์ฒฉํ•˜๋Š” ๊ฑด, ๊ทธ ํ•จ์ˆ˜๊ฐ€ ์–ด๋–ค ์ผ์„ ๋‹ฌ์„ฑํ•˜๊ธฐ ์œ„ํ•ด ์ž์‹ ์˜ ์™ธ๋ถ€ ๋ณ€์ˆ˜์— ์ง์ ‘ ์ ‘๊ทผํ•ด์•ผ ํ•  ๊ฒฝ์šฐ์—๋งŒ ์˜๋ฏธ๊ฐ€ ์žˆ๋‹ค.
  • ํ•˜์ง€๋งŒ ๋‚ด๋ถ€ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋Š” ๋ถˆํ•„์š”ํ•œ ์™ธ๋ถ€ ๋ฐ์ดํ„ฐ๋ฅผ ์ฐธ์กฐํ•˜๋Š” ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.
  • ์ด๋Ÿฐ ์ฝ”๋“œ๋ฅผ ์—ฐ์†์ฒด ์ „๋‹ฌ ์Šคํƒ€์ผ(continuation-passing style, CPS) ๋กœ ๋ฐ”๊พธ์–ด ๊ฐœ์„ ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.
var selector = document.querySelector;

selector('#search-button').addEventListener('click', handleClickEvent);

const processGrades = function (grades) {
// ํ•™์ƒ์˜ ์ ์ˆ˜ ๋ฆฌ์ŠคํŠธ๋ฅผ ์ฒ˜๋ฆฌ..
};

const handleMouseMovement = () =>
getJSON(`/students/${info.ssn}/grades`, processGrades);

const showStudent = function (info) {
selector('#student-info').innerHTML = info;
selector('#student-info').addEventListener(
'mouseover', handleMouseMovement
);
};

const handleError = error =>
console.log('error: ' + error.message);

const handleClickEvent = function (event) {
event.preventDefault();

let ssn = selector('#student-info').value;
if(!ssn) {
alert('์ž˜๋ชป๋œ ssn!');
return;
}
else {
getJSON(`/students/${ssn}`, showStudent).fail(handleError);
}
}
  • CPS๋Š” ๋น„์ฐจ๋‹จ ํ”„๋กœ๊ทธ๋žจ์˜ ์กฐ๊ฐ๋“ค์„ ๊ฐœ๋ณ„ ์ปดํฌ๋„ŒํŠธ๋กœ ๋ถ„๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์Šคํƒ€์ผ์ด๋‹ค.
  • ์—ฌ๊ธฐ์„œ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋Š” ํ˜„์žฌ ์—ฐ์†์ฒด(current continuation) ๋ผ๊ณ  ๋ถ€๋ฅด๋ฉฐ, ์ด ํ•จ์ˆ˜ ์ž์ฒด๋ฅผ ํ˜ธ์ถœ์ž์—๊ฒŒ ๋ฐ˜ํ™˜๊ฐ’์œผ๋กœ ๋Œ๋ ค์ค€๋‹ค.
  • CPS์˜ ์ค‘์š”ํ•œ ๊ฐ•์ ์€ ์ฝ˜ํ…์ŠคํŠธ ์Šคํƒ์˜ ํšจ์œจ์ด ์ข‹๋‹ค๋Š” ์ ์ด๋‹ค.
  • ์ด์–ด์ง€๋Š” ๊ณผ์ •์—์„œ ํ˜„์žฌ ํ•จ์ˆ˜์˜ ์ฝ˜ํ…์ŠคํŠธ๋ฅผ ์ •๋ฆฌํ•˜๊ณ  ์ƒˆ ์ฝ˜ํ…์ŠคํŠธ๋ฅผ ๋งŒ๋“ค์–ด ๋‹ค์Œ ํ•จ์ˆ˜๋ฅผ ์ง€์›ํ•˜๋Š” ์‹์œผ๋กœ ํ”„๋กœ๊ทธ๋žจ์˜ ํ๋ฆ„์„ ๊ณ„์† ์ด์–ด๊ฐ„๋‹ค.
  • CPS ์ฝ”๋”ฉ์€ ์ฝ”๋“œ์— ์ž”์กดํ•˜๋Š” ์ผ์‹œ์  ์˜์กด ๊ด€๊ณ„๋ฅผ ์ฒ™๊ฒฐํ•˜๊ณ , ๋น„๋™๊ธฐ ํ๋ฆ„์„ ์„ ํ˜•์ ์ธ ํ•จ์ˆ˜ ํ‰๊ฐ€ ํ˜•ํƒœ๋กœ ๋‘”๊ฐ‘์‹œํ‚ค๋Š” ๋Šฅ๋ ฅ์ด ์žˆ๋‹ค.

๐Ÿ“š ๋น„๋™๊ธฐ ๋กœ์ง์„ ํ”„๋ผ๋ฏธ์Šค๋กœ ์ผ๊ธ‰ํ™”โ€‹

  • ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์ด๋ผ๋ฉด ์ด๋Ÿฐ ํŠน์„ฑ์„ ์ง€๋…€์•ผ ํ•œ๋‹ค.
    1. ํ•ฉ์„ฑ๊ณผ ๋ฌด์ธ์ˆ˜ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ์ด์šฉํ•œ๋‹ค.
    2. ์ค‘์ฒฉ๋œ ๊ตฌ์กฐ๋ฅผ ๋ณด๋‹ค ์„ ํ˜•์ ์œผ๋กœ ํ๋ฅด๊ฒŒ ๋ˆŒ๋ ค ํŽธ๋‹ค.
    3. ์ผ์‹œ์  ๊ฒฐํ•ฉ์€ ์ถ”์ƒํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ฐœ๋ฐœ์ž๋Š” ๋” ์ด์ƒ ์‹ ๊ฒฝ ์“ธ ํ•„์š”๊ฐ€ ์—†๋‹ค.
    4. ์—ฌ๋Ÿฌ ์ฝœ๋ฐฑ ๋Œ€์‹ , ๋‹จ์ผ ํ•จ์ˆ˜๋กœ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋กœ์ง์„ ํ†ตํ•ฉํ•˜์—ฌ ์ฝ”๋“œ ํ๋ฆ„์„ ์›ํ• ํ•˜๊ฒŒ ํ•œ๋‹ค.
  • ๋ชจ๋‚˜๋“œ์—๋Š” ํ”„๋ผ๋ฏธ์Šค(promise) ๋ผ๋Š” ๊ฒƒ์ด ์กด์žฌํ•˜๋Š”๋ฐ ํ”„๋ผ๋ฏธ์Šค๋Š” ์˜ค๋ž˜ ๊ฑธ๋ฆฌ๋Š” ๊ณ„์‚ฐ์„ ๋ชจ๋‚˜๋“œ๋กœ ๊ฐ์‹ธ๋Š” ๊ฐœ๋…์ด๋‹ค.
  • ํ”„๋ผ๋ฏธ์Šค๋Š” ์˜ค๋ž˜ ๊ฑธ๋ฆฌ๋Š” ๊ณ„์‚ฐ์ด ๋๋‚  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ธ๋‹ค๊ฐ€ ๋ฏธ๋ฆฌ ๋งคํ•‘ํ•œ ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•œ๋‹ค.
  • ํ”„๋ผ๋ฏธ์Šค๋Š” ์šฐ์งํ•˜๊ณ  ํˆฌ๋ช…ํ•˜๊ฒŒ ๋ฐ์ดํ„ฐ๋ฅผ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๊ฐœ๋…์ด๋‹ค.
  • ํ”„๋ผ๋ฏธ์Šค๋Š” ๋‚˜์ค‘์— ์ฒ˜๋ฆฌ๊ฐ€ ๋๋‚˜๋Š” ๊ฐ’์ด๋‚˜ ํ•จ์ˆ˜๋ฅผ ๊ฐ์‹ผ๋‹ค.
  • ํ”„๋ผ๋ฏธ์Šค์˜ ์ƒํƒœ๋Š” ์–ธ์ œ๋‚˜ ๋ณด๋ฅ˜(pending), ์ด๋ฃธ(fulfilled), ๋ฒ„๋ฆผ(rejected), ๊ท€๊ฒฐ(settled) ํ•˜๋‚˜์ด๋‹ค.
  • ์ฒ˜์Œ์€ ๋ณด๋ฅ˜(๋ฏธ๊ฒฐ) ์ƒํƒœ๋กœ ์‹œ์ž‘ํ•˜๊ณ  ์˜ค๋ž˜ ๊ฑธ๋ฆฌ๋Š” ์ž‘์—… ๊ฒฐ๊ณผ์— ๋”ฐ๋ผ ์ด๋ฃธ(resolve) ๋˜๋Š” ๋ฒ„๋ฆผ(rejected) ์ƒํƒœ๋กœ ๋ถ„๊ธฐํ•œ๋‹ค.
  • ํ”„๋ผ๋ฏธ์Šค๊ฐ€ ๋ฌธ์ œ์—†์ด ์ด๋ฃจ์–ด์ง€๋ฉด ๋‹ค๋ฅธ ๊ฐ์ฒด์— ๋ฐ์ดํ„ฐ๊ฐ€ ๋‹น๋„ํ–ˆ์Œ์„ ํ†ต๋ณดํ•˜๊ณ , ์ฒ˜๋ฆฌ ๋„์ค‘ ์—๋Ÿฌ๊ฐ€ ๋‚˜๋ฉด ๋ฏธ๋ฆฌ ๋“ฑ๋กํ•œ ์‹คํŒจ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค. ์ด๋•Œ ํ”„๋ผ๋ฏธ์Šค๋Š” ๊ท€๊ฒฐ๋œ ์ƒํƒœ๋ผ๊ณ  ๋ณธ๋‹ค.
var fetchData = new Promise(function(resolve, reject) {
// ๋น„๋™๊ธฐ ํ˜น์€ ์˜ค๋ž˜ ๊ฑธ๋ฆฌ๋Š” ๊ณ„์‚ฐ์„ ํ•œ๋‹ค.
if (์„ฑ๊ณตํ•˜๋ฉด) {
resolve(result);
}
else {
reject(new Error('error'));
}
});
  • ํ”„๋ผ๋ฏธ์Šค ์ƒ์„ฑ์ž๋Š” ๋น„๋™๊ธฐ ์ž‘์—…์„ ๊ฐ์‹ผ ํ•จ์ˆ˜(์•ก์…˜ ํ•จ์ˆ˜)๋ฅผ ๋ฐ›๊ณ  ์ด ํ•จ์ˆ˜๋Š” resolve์™€ reject ์ฝœ๋ฐฑ 2๊ฐœ๋ฅผ ๋ฐ›๊ณ , ๊ฐ๊ฐ ํ”„๋ผ๋ฏธ์Šค๊ฐ€ ์ด๋ฃธ/๋ฒ„๋ฆผ ์ƒํƒœ์ผ ๋•Œ ํ˜ธ์ถœ๋œ๋‹ค.
var Scheduler = (function () {
let delayedFn = _.bind(setTimeout, undefined, _, _);

return {
delay5: _.partial(delayedFn, _, 5000),
delay10: _.partial(delayedFn, _, 10000),
delay: _.partial(delayedFn, _, _),
};
})();

var promiseDemo = new Promise(function(resolve, reject) {
Scheduler.delay5(function () { // ์˜ค๋ž˜๊ฑธ๋ฆฌ๋Š” ์ž‘์—…์„ ์ง€์—ฐ ํ•จ์ˆ˜๋กœ ๋‚˜ํƒ€๋‚ธ๋‹ค.
resolve('์™„๋ฃŒ!');
});
});

promiseDemo.then(function(status) {
console.log('5์ดˆ ํ›„ ์ƒํƒœ: '+ status); // 5์ดˆ ํ›„ ํ”„๋ผ๋ฏธ์Šค๊ฐ€ ๊ท€๊ฒฐ๋œ๋‹ค.
})

๐ŸŽˆ ๋ฏธ๋ž˜์˜ ๋ฉ”์„œ๋“œ ์ฒด์ธโ€‹

  • ํ”„๋ผ๋ฏธ์Šค ๊ฐ์ฒด๋Š” then ๋ฉ”์„œ๋“œ๋ฅผ ์ง€๋‹ˆ๋Š”๋ฐ ํ”„๋ผ๋ฏธ์Šค์— ๋ณด๊ด€๋œ ๋ฐ˜ํ™˜๊ฐ’์— ์–ด๋–ค ์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰ํ•˜๊ณ  ๋‹ค์‹œ ํ”„๋ผ๋ฏธ์Šค ํ˜•ํƒœ๋กœ ๋˜๋Œ๋ฆฌ๋Š” ๋ฉ”์„œ๋“œ์ด๋‹ค.
  • API๋ฅผ ํ”„๋ผ๋ฏธ์Šคํ™”ํ•˜๋ฉด ๊ธฐ์กด ์ฝœ๋ฐฑ๋ณด๋‹ค ํ›จ์”ฌ ์ฝ”๋“œ๋ฅผ ๋‹ค๋ฃจ๊ธฐ ์‰ฌ์›Œ์ง„๋‹ค.
getJSON('/students')
.then(hide('spinner')) // ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜์ง€ ์•Š๋Š” ํ•จ์ˆ˜๋ผ์„œ ํ”„๋ผ๋ฏธ์Šค๋กœ ๊ฐ์‹ผ ๊ฐ’์€ ํ›„์† then์œผ๋กœ ๋„˜๊ธด๋‹ค.
.then(R.filter(s => s.address.country == 'US'))
.then(R.sortBy(R.prop('ssn')))
.then(R.map(student => {
return getJSON('/grades?ssn='+ student.ssn)
.then(R.compose(Math.ceil,
fork(R.divide, R.sum, R.length))) // ํ•จ์ˆ˜ ์กฐํ•ฉ๊ธฐ์™€ ๋žŒ๋‹ค JS ํ•จ์ˆ˜๋กœ ํ‰๊ท ์„ ๊ณ„์‚ฐ
.then(grade =>
IO.of(R.merge(student,
{ 'grade': grade })) // IO ๋ชจ๋‚˜๋“œ๋กœ ํ•™์ƒ๊ณผ ์ ์ˆ˜ ๋ฐ์ดํ„ฐ๋ฅผ DOM์— ํ‘œ์‹œํ•œ๋‹ค.
.map(R.props(['ssn', 'firstname', 'lastname', 'grade']))
.map(csv)
.map(append('#student-info')).run())
}))
.catch(function(error) {
console.log('error: '+ error.message);
});
  • ๋น„๋™๊ธฐ ํ˜ธ์ถœ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ์„ธ๋ถ€ ๋กœ์ง์„ ํ”„๋ผ๋ฏธ์Šค๊ฐ€ ๋Œ€์‹  ์ฒ˜๋ฆฌํ•˜๋ฏ€๋กœ ๋งˆ์น˜ ๊ฐ ํ•จ์ˆ˜๋ฅผ ์ˆœ์„œ๋Œ€๋กœ ํ•˜๋‚˜์”ฉ ์‹คํ–‰ํ•˜๋“ฏ ํ”„๋กœ๊ทธ๋žจ์„ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์ด๋Ÿฐ ์ˆ˜์ค€์˜ ์œ ์—ฐ์„ฑ์„ ์œ„์น˜ ํˆฌ๋ช…์„ฑ์ด๋ผ๊ณ  ํ•œ๋‹ค.
  • Promise.all์„ ์ด์šฉํ•˜๋ฉด ํ•œ ๋ฒˆ์— ์—ฌ๋Ÿฌ ๋ฐ์ดํ„ฐ๋ฅผ ๋‚ด๋ ค๋ฐ›๋Š” ๋ธŒ๋ผ์šฐ์ €์˜ ๋Šฅ๋ ฅ์„ ๊ทน๋Œ€ํ™”ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์ดํ„ฐ๋Ÿฌ๋ธ” ์ธ์ˆ˜์— ํฌํ•จ๋œ ๋ชจ๋“  ํ”„๋ผ๋ฏธ์Šค๊ฐ€ ๊ท€๊ฒฐ๋˜๋Š” ์ฆ‰์‹œ ๊ฒฐ๊ณผ ํ”„๋ผ๋ฏธ์Šค๋„ ๊ท€๊ฒฐ๋œ๋‹ค.

๐ŸŽˆ ๋™๊ธฐ/๋น„๋™๊ธฐ ๋กœ์ง์„ ํ•ฉ์„ฑโ€‹

  • ์•„๋ž˜ ์ฝ”๋“œ์—์„œ ์ค‘์š”ํ•œ ๊ฑด student ๊ฐ์ฒด๊ฐ€ ์กด์žฌํ•˜๋ฉด ์ด ๊ฐ์ฒด๋กœ ํ”„๋ผ๋ฏธ์Šค๊ฐ€ ๊ท€๊ฒฐ๋˜๋ฉฐ ๊ทธ ์™ธ์—๋Š” ๋ฒ„๋ ค์ง„๋‹ค๋Š” ์‚ฌ์‹ค์ด๋‹ค.
// ๋ธŒ๋ผ์šฐ์ €์˜ IndexedDB์‚ฌ์šฉ
const find = function(db, ssn) {
let trans = db.transaction(['students'], 'readonly');
const store = trans.objectStore('students');
return new Promise(function(resolve, reject) {
let request = store.run(ssn);
request.onerror = function() {
if(reject) {
reject(new Error('error')); // ์‹คํŒจ
}
};
request.onsuccess = function() {
resolve(request.result); // ์„ฑ๊ณต
}
})
}
  • ํ”„๋ผ๋ฏธ์Šค๋Š” ์ฝ”๋“œ๋ฅผ ๊ฑฐ์˜ ๊ณ ์น˜์ง€ ์•Š์•„๋„ ๋ฏธ๋ž˜์˜ ํ•จ์ˆ˜ ํ•ฉ์„ฑ๊ณผ ๋™๋“ฑํ•˜๊ฒŒ ํ•จ์ˆ˜๋ฅผ ํ”„๋ผ๋ฏธ์Šค์™€ ํ•ฉ์„ฑํ•  ์ˆ˜ ์žˆ๋„๋ก ๋น„๋™๊ธฐ ์ฝ”๋“œ์˜ ์‹คํ–‰์„ ์ถ”์ƒํ•œ๋‹ค.
  • ๋„์šฐ๋ฏธ ํ•จ์ˆ˜๋ฅผ ์ž‘์„ฑํ•œ๋‹ค.
const fetchStudentDBAsync = R.curry(function(db, ssn) {
return find(db, ssn);
});

// ์ด ํ•จ์ˆ˜๋ฅผ ํ•ฉ์„ฑ์— ํฌํ•จํ•˜๊ธฐ ์œ„ํ•ด ์ €์žฅ์†Œ ๊ฐ์ฒด๋ฅผ ์ปค๋ฆฌํ•œ๋‹ค.
const findStudentAsync = fetchStudentDBAsync(db);

// ๋ฐ๋„ˆ๋ธ”ํ˜•์—๋„ ์—ฐ์‚ฐ์„ ์ฒด์ด๋‹ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋งŒ๋“ ๋‹ค.
const then = R.curry(function (f, thenable) {
return thenable.then(f);
});

const catchP = R.curry(function (f, promise) {
return promise.catch(f);
});

// ์ฝ˜์†”์— ์—๋Ÿฌ ์ˆ˜์ค€์˜ ๋กœ๊ฑฐ๋ฅผ ๋งŒ๋“ ๋‹ค.
const errorLog = _.partial(logger, 'console', 'basic', 'ShowStudentAsync', 'ERROR');
  • R.compose๋กœ ๋ฌถ๋Š”๋‹ค.
const ShowStudentAsync = R.compose(
catchP(errorLog), // ์—๋Ÿฌ๋Š” ๋ชจ๋‘ ์—ฌ๊ธฐ
then(append('#student-info')), // then์€ ๋ชจ๋‚˜๋“œ map๊ณผ ๊ฐ™๋‹ค
then(csv),
then(R.props(['ssn', 'firstname', 'lastname'])),
chain(findStudentAsync), // ๋™๊ธฐ/๋น„๋™๊ธฐ ์ฝ”๋“œ๊ฐ€ ์„œ๋กœ ๋งž๋ฌผ๋ ค ๊ตด์ ˆ๋˜๋Š” ์ง€์ 
map(checkLengthSsn),
lift(cleanInput)
);
  • ํ•จ์ˆ˜๊ฐ€ ๋‚ด๋ถ€์ ์œผ๋กœ ์–ด๋–ค ๋น„๋™๊ธฐ ๋กœ์ง์„ ๊ตฌ์‚ฌํ–ˆ๋Š”์ง€, ์–ด๋–ค ์ฝœ๋ฐฑ์„ ์ผ๋Š”์ง€ ๋“ฑ์€ ์ฒ ์ €ํžˆ ๋ฒ ์ผ์— ๊ฐ์‹ผ ์ฑ„ ์„ ์–ธ์ ์ธ ํฌ์ฆˆ๋ฅผ ์ทจํ•œ๋‹ค.
  • ๋”ฐ๋ผ์„œ ๋™์‹œ์— ์‹คํ–‰๋˜์ง€ ์•Š์ง€๋งŒ ๋‚˜์ค‘์— ํ•จ์ˆ˜ ์กฐํ•ฉ๊ธฐ๋กœ์„œ์˜ ๋ณธ์ƒ‰์„ ๋“œ๋Ÿฌ๋‚ผ ํ•จ์ˆ˜๋ฅผ ์„œ๋กœ ๋ถ™์—ฌ๋†“์€ ๋ฌด์ธ์ˆ˜ ํ”„๋กœ๊ทธ๋žจ๋“ค์„ ํ•ฉ์„ฑํ•˜์—ฌ ์กฐ์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ“š ๋Š๊ธ‹ํ•œ ๋ฐ์ดํ„ฐ ์ƒ์„ฑโ€‹

  • ์ œ๋„ˆ๋ ˆ์ดํ„ฐ ํ•จ์ˆ˜๋Š” function*๋ผ๊ณ  ํ‘œ๊ธฐํ•˜๋Š”, ์–ธ์–ด ์ˆ˜์ค€์—์„œ ์ง€์›๋˜๋Š” ์žฅ์น˜์ด๋‹ค.
  • ์ด ํ•จ์ˆ˜๋Š” yield๋ฅผ ๋งŒ๋‚˜๋ฉด ํ•จ์ˆ˜ ๋ฐ–์œผ๋กœ ์ž ์‹œ ๋‚˜๊ฐ”๋‹ค๊ฐ€ ์ž์‹ ์˜ ๋ณด๊ด€๋œ ์ฝ˜ํ…์ŠคํŠธ๋ฅผ ์ฐพ์•„ ๋‹ค์‹œ ๋Œ์•„์˜จ๋‹ค.
  • ์ œ๋„ˆ๋ ˆ์ดํ„ฐ ํ•จ์ˆ˜์˜ ์‹คํ–‰ ์ฝ˜ํ…์ŠคํŠธ๋Š” ์ž ์ • ์ค‘๋‹จํ–ˆ๋‹ค๊ฐ€ ์–ธ์ œ๋ผ๋„ ์žฌ๊ฐœํ•  ์ˆ˜ ์žˆ์–ด์„œ ์ œ๋„ˆ๋ ˆ์ดํ„ฐ๋กœ ๋‹ค์‹œ ๋Œ์•„์˜ฌ ์ˆ˜ ์žˆ๋‹ค.
  • ์ œ๋„ˆ๋ ˆ์ดํ„ฐ๋Š” ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ์‹œ์ ์— ๋‚ด๋ถ€์ ์œผ๋กœ ์ดํ„ฐ๋ ˆ์ดํ„ฐ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ๋Š๊ธ‹ํ•จ์„ ๋ถ€์—ฌํ•˜๊ณ , ์ดํ„ฐ๋ ˆ์ดํ„ฐ๋Š” ๋งค๋ฒˆ yield๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ๋งˆ๋‹ค ํ˜ธ์ถœ์ž์—๊ฒŒ ๋ฐ์ดํ„ฐ๋ฅผ ๋Œ๋ ค์ค€๋‹ค.

๐ŸŽˆ ์ œ๋„ˆ๋ ˆ์ดํ„ฐ์™€ ์žฌ๊ท€โ€‹

  • ์ œ๋„ˆ๋ ˆ์ดํ„ฐ๋„ ๋‹ค๋ฅธ ์ œ๋„ˆ๋ ˆ์ดํ„ฐ๋ฅผ ์–ผ๋งˆ๋“ ์ง€ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์ค‘์ฒฉ๋œ ๊ฐ์ฒด ์ง‘ํ•ฉ์„ ํ‰ํ‰ํ•œ ๋ชจ์–‘์œผ๋กœ ๋งŒ๋“ค๊ณ  ์‹ถ์„ ๋•Œ ์•„์ฃผ ์œ ์šฉํ•œ ํŠน์„ฑ์ด๋‹ค.
  • ์ œ๋„ˆ๋ ˆ์ดํ„ฐ๋Š” for..of ๋ฃจํ”„๋ฌธ์œผ๋กœ ๋ฐ˜๋ณตํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค๋ฅธ ์ œ๋„ˆ๋ ˆ์ดํ„ฐ์—๊ฒŒ ์œ„์ž„ํ•˜๋Š” ๊ฑด ๋งˆ์น˜ ๋‘ ์ปฌ๋ ‰์…˜์„ ๋ณ‘ํ•ฉํ•œ ์ „์ฒด ์ปฌ๋ ‰์…˜์„ ๋ฐ˜๋ณตํ•˜๋Š” ๊ฒƒ๊ณผ ๋น„์Šทํ•˜๋‹ค.
function* AllStudentsGenerator() {
yield 'Church';

yield 'Rosser';
yield* RosserStudentGenerator(); // yield*๋กœ ๋‹ค๋ฅธ ์ œ๋„ˆ๋ ˆ์ดํ„ฐ์—๊ฒŒ ์œ„์ž„ํ•œ๋‹ค.

yield 'Turing';
yield* TuringStudentGenerator();

yield 'Kleene';
yield* KleeneStudentGenerator();
}

function* RosserStudentGenerator() {
yield 'Mendelson';
yield 'Sacks';
}

function* TuringStudentGenerator() {
yield 'Gandy';
yield 'Sacks';
}

function* KleeneStudentGenerator() {
yield 'Nelson';
yield 'Constable';
}

for (let student of AllStudentsGenerator()) {
console.log(student);
}

// Church
// Rosser
// Mendelson
// Sacks
// Turing
// Gandy
// Sacks
// Kleene
// NelsonA
  • ์žฌ๊ท€๋กœ ํƒ์ƒ‰ํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.
function* TreeTraversal(node) {
yield node.value;
if (node.hasChildren()) {
for (let child of node.children) {
yield* TreeTraversal(child);
}
}
}

var root = node(new Person('Alonzo', 'Church', '111-11-1231'));

for (let person of TreeTraversal(root)) {
console.log(person.lastname);
}

// Church
// Rosser
// Mendelson
// Sacks
// Turing
// Gandy
// Sacks
// Kleene
// NelsonA

๐ŸŽˆ ์ดํ„ฐ๋ ˆ์ดํ„ฐ ํ”„๋กœํ† ์ฝœโ€‹

  • ์ œ๋„ˆ๋ ˆ์ดํ„ฐ๋Š” ์ดํ„ฐ๋ ˆ์ดํ„ฐ ์™€ ๋ฐ€์ ‘ํ•œ ๊ด€๊ณ„๊ฐ€ ์žˆ๋Š”๋ฐ ์—ฌ๋Š ์ž๋ฃŒ๊ตฌ์กฐ์ฒ˜๋Ÿผ ๋ฃจํ”„๋กœ ๋ฐ˜๋ณต์‹œํ‚ฌ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ๋„ ์ดํ„ฐ๋ ˆ์ดํ„ฐ ๋•๋ถ„์ด๋‹ค.
  • ์ œ๋„ˆ๋ ˆ์ดํ„ฐ ํ•จ์ˆ˜๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ ์ดํ„ฐ๋ ˆ์ดํ„ฐ ํ”„๋กœํ† ์ฝœ์— ๋”ฐ๋ผ yield ํ‚ค์›Œ๋“œ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋Š” next() ๋ฉ”์„œ๋“œ๊ฐ€ ๊ตฌํ˜„๋œ Generator ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
  • Generator ๊ฐ์ฒด์˜ ์†์„ฑ์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.
    1. done: ์ œ์ผ ๋งˆ์ง€๋ง‰์— ์ดํ„ฐ๋ ˆ์ดํ„ฐ๊ฐ€ ์ „๋‹ฌ๋˜๋ฉด true, ๊ทธ ์™ธ์—๋Š” false๋กœ ์„ธํŒ…๋œ๋‹ค. ์ฆ‰, false๋Š” ์ดํ„ฐ๋ ˆ์ดํ„ฐ๊ฐ€ ์•„์ง ๋„์ค‘์— ๋‹ค๋ฅธ ๊ฐ’์„ ์ƒ์‚ฐํ•  ์ˆ˜ ์žˆ์Œ์„ ์˜๋ฏธํ•œ๋‹ค.
    2. value: ์ดํ„ฐ๋ ˆ์ดํ„ฐ๊ฐ€ ๋ฐ˜ํ™˜ํ•œ ๊ฐ’์ด๋‹ค.
  • ๋‹ค์Œ์€ range ์ œ๋„ˆ๋ ˆ์ดํ„ฐ๋ฅผ ์›์‹œ ํ˜•ํƒœ๋กœ ๊ตฌํ˜„ํ•œ ์ฝ”๋“œ์ด๋‹ค.
function range(start, end) {
return {
[Symbol.iterator]() {
return this; // ๋ฐ˜ํ™˜๋œ ๊ฐ์ฒด๊ฐ€ ์ดํ„ฐ๋Ÿฌ๋ธ”์ž„์„ ๋‚˜ํƒ€๋‚ธ๋‹ค.
},
next() {
if(start < end) {
// ๋” ์ƒ์„ฑํ•  ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ์œผ๋ฉด done์— false๋ฅผ ์„ธํŒ…
return { value: start++, done: false };
}
// ์—†์œผ๋ฉฐ done์— true๋ฅผ ์„ธํŒ…
return { done: true, value: end };
}
};
}
  • ์ด๋ ‡๊ฒŒ ์ œ๋„ˆ๋ ˆ์ดํ„ฐ๋ฅผ ๊ตฌํ˜„ํ•˜๋ฉด ํŠน์ •ํ•œ ํŒจํ„ด์ด๋‚˜ ๋ช…์„ธ๋ฅผ ๋”ฐ๋ฅด๋Š” ์–ด๋–ค ์ข…๋ฅ˜์˜ ๋ฐ์ดํ„ฐ๋ผ๋„ ๋งŒ๋“ค์–ด๋‚ผ ์ˆ˜ ์žˆ๋‹ค.
  • ๋‹ค์Œ์€ ์ œ๊ณฑ์ˆ˜ ์ œ๋„ˆ๋ ˆ์ดํ„ฐ๋ฅผ ๋งŒ๋“  ๊ฒƒ์ด๋‹ค.
function squares() {
let n = 1;
return {
[Symbol.iterator]() {
return this;
},
next() {
return { value: n * n++ };
}
};
}

๐Ÿ“š RxJS๋ฅผ ์‘์šฉํ•œ ํ•จ์ˆ˜ํ˜• ๋ฆฌ์•กํ‹ฐ๋ธŒ ํ”„๋กœ๊ทธ๋ž˜๋ฐโ€‹

  • RxJS๋Š” ํ•จ์ˆ˜ํ˜• ํ”„๋ผ๋ฏธ์Šค ๊ธฐ๋ฐ˜๊ณผ ๋น„์Šทํ•œ ๋ฐฉ์‹์œผ๋กœ ์ž‘๋™ํ•˜์ง€๋งŒ, ๋” ๋†’์€ ์ˆ˜์ค€์˜ ์ถ”์ƒํ™”๋ฅผ ์ œ๊ณตํ•˜๋ฉฐ ๋” ๊ฐ•๋ ฅํ•œ ์—ฐ์‚ฐ์„ ์ œ๊ณตํ•œ๋‹ค.

๐ŸŽˆ ์˜ต์ €๋ฒ„๋ธ” ์ˆœ์ฐจ์—ด๋กœ์„œ์˜ ๋ฐ์ดํ„ฐโ€‹

  • ์˜ต์ €๋ฒ„๋ธ”(observable) ์€ ๊ตฌ๋…(subscribe) ๊ฐ€๋Šฅํ•œ ๋ชจ๋“  ๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค.
  • ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ํŒŒ์ผ ์ฝ๊ธฐ, ์›น ์„œ๋น„์Šค ํ˜ธ์ถœ, DB ์ฟผ๋ฆฌ, ์‹œ์Šคํ…œ ํ†ต์ง€ ํ‘ธ์‹œ, ์‚ฌ์šฉ์ž ์ž…๋ ฅ ์ฒ˜๋ฆฌ, ์›์†Œ ์ปฌ๋ ‰์…˜ ํƒ์ƒ‰, ๋‹จ์ˆœ ๋ฌธ์ž์—ด ํŒŒ์‹ฑ ๋“ฑ์œผ๋กœ ๋น„๋กฏ๋œ ๋น„๋™๊ธฐ ์ด๋ฒคํŠธ๋ฅผ ๊ตฌ๋…ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ๋ฆฌ์•กํ‹ฐ๋ธŒ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์€ ๋ชจ๋“  ๋ฐ์ดํ„ฐ ์ œ๊ณต์›(data provider)์„ Rx.Observable ๊ฐ์ฒด๋ฅผ ํ†ตํ•ด ์˜ต์ €๋ฒ„๋ธ” ์ŠคํŠธ๋ฆผ(observable stream) ์ด๋ผ๋Š” ๋‹จ์ผ ๊ฐœ๋…์œผ๋กœ ์ผ์›ํ™”ํ•œ๋‹ค.
  • ์ŠคํŠธ๋ฆผ์ด๋ž€ ์‹œ๊ฐ„์˜ ํ๋ฆ„์— ๋”ฐ๋ผ ๋ฐœ์ƒํ•˜๋Š” ์ด๋ฒคํŠธ์˜ ์ˆœ์ฐจ์—ด์ด๋‹ค.
  • ๊ฐ’์„ ์ถ”์ถœํ• ๋ ค๋ฉด ๊ตฌ๋…์€ ํ•„์ˆ˜์ด๋‹ค.
Rx.Observable.range(1, 3)
.subscribe(
x => console.log(`๋‹ค์Œ: ${x}`),
err => console.log(`error: ${err}`),
() => console.log('์™„๋ฃŒ!'),
);

// ๋‹ค์Œ: 1
// ๋‹ค์Œ: 2
// ๋‹ค์Œ: 3
// ์™„๋ฃŒ!
  • ์ œ๊ณฑ์ˆ˜ ์ œ๋„ˆ๋ ˆ์ดํ„ฐ ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•ด์„œ ๊ฐ’ ์ŠคํŠธ๋ฆฝ์„ ์ฑ„์šด๊ฒƒ์ด๋‹ค.
const squares = Rx.Observable.wrap(function* (n) {
for(let i = 1; i <= n; i++) {
return yield Observable.just(i * i);
}
});

squares(3).subscribe(x => console.log(`๋‹ค์Œ: ${x}`));

// ๋‹ค์Œ: 1
// ๋‹ค์Œ: 4
// ๋‹ค์Œ: 9
  • Rx.Observable๋กœ ์–ด๋–ค ์˜ต์ €๋ฒ„๋ธ” ๊ฐ์ฒด๋ผ๋„ ๊ฐ์‹ธ๊ฑฐ๋‚˜ ์Šน๊ธ‰ํ•˜๋ฉด ๊ด€์ฐฐ๋œ ๊ฐ’์— ์ƒ์ดํ•œ ํ•จ์ˆ˜๋ฅผ ๋งคํ•‘/์ ์šฉํ•ด์„œ ์›ํ•˜๋Š” ์ถœ๋ ฅ์„ ์–ป๋„๋ก ๋ณ€ํ™˜ํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ฒฐ๊ตญ ๋ชจ๋‚˜๋“œ์ด๋‹ค.

๐ŸŽˆ ํ•จ์ˆ˜ํ˜• ๋ฆฌ์•กํ‹ฐ๋ธŒ ํ”„๋กœ๊ทธ๋ž˜๋ฐโ€‹

  • Rx.Observable ๊ฐ์ฒด๋Š” ํ•จ์ˆ˜ํ˜•๊ณผ ๋ฆฌ์•กํ‹ฐ๋ธŒ, ๋‘ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์„ธ์ƒ์„ ํ•˜๋‚˜๋กœ ๋ฌถ๋Š”๋‹ค.
  • ์ด ๊ฐ์ฒด๋Š” map, of, join ๋“ฑ ์ตœ์†Œํ•œ์˜ ๋ชจ๋‚˜๋“œ ์ธํ„ฐํŽ˜์ด์Šค์— ํ•ด๋‹นํ•˜๋Š” ๊ตฌํ˜„์ฒด์™€ ์ŠคํŠธ๋ฆผ ์กฐ์ž‘์— ํŠนํ™”๋œ ๋ฉ”์„œ๋“œ๋ฅผ ์—ฌ๋Ÿฟ ๊ฑฐ๋Š๋ฆฐ๋‹ค.
Rx.Observable.of(1, 2, 3, 4, 5)
.filter(x => x % 2 !== 0)
.map(x => x * x)
.subscribe(x => console.log(`๋‹ค์Œ: ${x}`));

// ๋‹ค์Œ: 1
// ๋‹ค์Œ: 9
// ๋‹ค์Œ: 25
  • ๋‹ค์Œ์€ SSN ํ•„๋“œ ์ž…๋ ฅ๊ฐ’์ด ์˜ฌ๋ฐ”๋ฅธ์ง€ ๊ฒ€์ฆํ•˜๋Š” ์˜ˆ์ œ์ด๋‹ค.
document.querySelector('#student-ssn')
.addEventListener('change', function(event) {
let value = event.target.value;
value = value.replace(/^\s*|\-|\s*$/g, '');
console.log(value.length !== 9 ? '๋งž์Œ' : 'ํ‹€๋ฆผ');
});

// 444 ๋งž์Œ
// 444-44-4444 ํ‹€๋ฆผ
  • change ์ด๋ฒคํŠธ๊ฐ€ ๋น„๋™๊ธฐ๋กœ ๋ฐœ์ƒํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์–ด์ฉ” ์ˆ˜ ์—†์ด ์ฝœ๋ฐฑ ํ•จ์ˆ˜ ํ•˜๋‚˜์— ๋น„์ง€๋‹ˆ์Šค ๋กœ์ง์„ ๋ชฐ์•„๋„ฃ์—ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋กœ์ง์„ ์ถ”๊ฐ€ํ• ์ˆ˜๋ก ์ ์  ๋ณต์žกํ•ด์ง„๋‹ค.
  • ์ด๋ฒคํŠธ์™€ ํ•จ์ˆ˜ํ˜• ๋‘ ์„ธ๊ณ„๋ฅผ ์ ‘๋ชฉ์‹œํ‚ค๊ธฐ ์œ„ํ•ด Rx.Observable๋กœ ์ถ”์ƒํ™” ๊ณ„์ธต์„ ๋‘”๋‹ค.
  • ์ด๋ฒคํŠธ๋ฅผ ๊ตฌ๋…ํ•˜๊ณ  ๋น„์ง€๋‹ˆ์Šค ๋กœ์ง์€ ๋ชจ๋‘ ์ˆœ์ˆ˜ํ•จ์ˆ˜๋กœ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.
Rx.Observable.fromEvent(
document.querySelector('#student-ssn'), 'change')
.map(x => x.target.value)
.map(cleanInput) // SSN ๊ฐ’์„ ์ •์ œํ•œ๋‹ค
.map(checkLengthSsn)
.subscribe( // Either.Right, Either.Left ์ค‘ ์–ด๋Š ์ชฝ์ธ์ง€ ์ฒดํฌํ•˜์—ฌ ์˜ฌ๋ฐ”๋ฅธ์ง€ ์—ฌ๋ถ€๋ฅผ ํŒ๋‹จํ•œ๋‹ค.
ssn => ssn.isRight ? console.log('Valid') : console.log('Invalid')
);

๐ŸŽˆ RxJS์™€ ํ”„๋ผ๋ฏธ์Šคโ€‹

  • RxJS๋Š” ๋ชจ๋“  ํ”„๋ผ๋ฏธ์Šค/A+ ํ˜ธํ™˜ ๊ฐ์ฒด๋ฅผ ์˜ต์ €๋ฒ„๋ธ” ์ˆœ์ฐจ์—ด๋กœ ๋ณ€ํ™˜ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์ฆ‰, ์‹คํ–‰ ์‹œ๊ฐ„์ด ๊ธด getJSON ํ•จ์ˆ˜๋ฅผ ๊ฐ์‹ธ ๊ท€๊ฒฐ ์‹œ์ ์— ๊ทธ ๊ฐ’์„ ์ŠคํŠธ๋ฆผ์œผ๋กœ ๋ฐ”๊พผ๋‹ค.
Rx.Observable.fromPromise(getJSON('/students'))
// ๋ชจ๋“  ํ•™์ƒ ๊ฐ์ฒด๋ฅผ ๋Œ€์†Œ๋ฌธ์ž ๊ตฌ๋ถ„ ์—†์ด ์ด๋ฆ„ ์ˆœ์œผ๋กœ ์ •๋ ฌํ•œ๋‹ค.
.map(R.sortBy(R.compose(R.toLower, R.prop('firstname'))))
// ํ•˜๋‚˜์˜ ํ•™์ƒ ๊ฐ์ฒด ๋ฐฐ์—ด์„ ์˜ต์ €๋ฒ„๋ธ”ํ•œ ํ•™์ƒ ์ˆœ์ฐจ์—ด๋กœ ๋ฐ”๊พผ๋‹ค.
.flatMapLatest(student => Rx.Observable.from(student))
// ๋ฏธ๊ตญ์— ์‚ด์ง€ ์•Š๋Š” ํ•™์ƒ ๊ฑฐ๋ฅด๊ธฐ
.filter(R.pathEq(['address', 'country'], 'US'))
.subscribe(
student => console.log(student.fullname),
err => console.log(err)
);

๐Ÿ“š ๋งˆ์น˜๋ฉฐโ€‹

  • ํ”„๋ผ๋ฏธ์Šค๋Š” ์˜ค๋žซ๋™์•ˆ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํ”„๋กœ๊ทธ๋ž˜๋จธ๋“ค์˜ ๊ณจ๋จธ๋ฆฌ๋ฅผ ์•“์•„์˜จ, ์ฝœ๋ฐฑ ์ค‘์‹ฌ์ ์ธ ์„ค๊ณ„๋ฅผ ํ•จ์ˆ˜ํ˜•์œผ๋กœ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐฉ์•ˆ์ด๋‹ค.
  • "๋ฏธ๋ž˜์˜" ํ•จ์ˆ˜๋ฅผ ํ”„๋ผ๋ฏธ์Šค๋กœ ํ•ฉ์„ฑ, ์ฒด์ด๋‹ํ•˜๋ฉด ์ผ์‹œ์ ์œผ๋กœ ์˜์กด ๊ด€๊ณ„๊ฐ€ ํ˜•์„ฑ๋œ ์ฝ”๋“œ์˜ ์žก๋‹คํ•œ ์ €์ˆ˜์ค€ ๋กœ์ง์„ ์ถ”์ƒํ™”ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์ œ๋„ˆ๋ ˆ์ดํ„ฐ๋Š” ๋น„๋™๊ธฐ ์ฝ”๋“œ์— ์ ‘๊ทผํ•˜๋Š” ๋˜ ๋‹ค๋ฅธ ๋ฐฉ์•ˆ์œผ๋กœ, ๋Š๊ธ‹ํ•œ ์ดํ„ฐ๋ ˆ์ดํ„ฐ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์“ธ ์ˆ˜ ์žˆ๋Š” ์‹œ์ ์— ๋‚ด์–ด์ค€ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์žฅ์น˜์ด๋‹ค.
  • ํ•จ์ˆ˜ํ˜• ๋ฆฌ์•กํ‹ฐ๋ธŒ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์€ ํ”„๋กœ๊ทธ๋žจ์˜ ์ถ”์ƒํ™” ์ˆ˜์ค€์„ ๋†’์—ฌ ์ด๋ฒคํŠธ๋ฅผ ๋…ผ๋ฆฌ์ ์œผ๋กœ ๋…๋ฆฝ๋œ ๋‹จ์œ„๋กœ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๊ฒŒ ํ•œ๋‹ค.