๐ Chapter 8: ๋น๋๊ธฐ ์ด๋ฒคํธ์ ๋ฐ์ดํฐ๋ฅผ ๊ด๋ฆฌ
๐ ๊ณจ์นซ๋ฉ์ด ๋น๋๊ธฐ ์ฝ๋โ
- ๋น์ฐจ๋จ ๋น๋๊ธฐ ํธ์ถ ์ฝ๋๋ฅผ ๊ตฌํํ์ฌ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋๋ฐ ๋ค์๊ณผ ๊ฐ์ ๋ฌธ์ ๊ฐ ๋ฐ๋ชฉ์ ์ก๋๋ค.
- ํจ์ ๊ฐ์ ์ผ์์ ์์กด ๊ด๊ณ๊ฐ ํ์ฑ
- ์ด์ฉ ์ ์์ด ์ฝ๋ฐฑ ํผ๋ผ๋ฏธ๋ ๋ช์ ๋น ์ง
- ๋๊ธฐ/๋น๋๊ธฐ ์ฝ๋์ ํธํ๋์ง ์๋ ์กฐํฉ
๐ ํจ์ ๊ฐ์ ์ผ์์ ์์กด ๊ด๊ณ๊ฐ ํ์ฑโ
- ์ผ์์ ๊ฒฐํฉ(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 ์ฝ๋ฉ์ ์ฝ๋์ ์์กดํ๋ ์ผ์์ ์์กด ๊ด๊ณ๋ฅผ ์ฒ๊ฒฐํ๊ณ , ๋น๋๊ธฐ ํ๋ฆ์ ์ ํ์ ์ธ ํจ์ ํ๊ฐ ํํ๋ก ๋๊ฐ์ํค๋ ๋ฅ๋ ฅ์ด ์๋ค.
๐ ๋น๋๊ธฐ ๋ก์ง์ ํ๋ผ๋ฏธ์ค๋ก ์ผ๊ธํโ
- ํจ์ํ ํ๋ก๊ทธ๋๋ฐ์ด๋ผ๋ฉด ์ด๋ฐ ํน์ฑ์ ์ง๋
์ผ ํ๋ค.
- ํฉ์ฑ๊ณผ ๋ฌด์ธ์ ํ๋ก๊ทธ๋๋ฐ์ ์ด์ฉํ๋ค.
- ์ค์ฒฉ๋ ๊ตฌ์กฐ๋ฅผ ๋ณด๋ค ์ ํ์ ์ผ๋ก ํ๋ฅด๊ฒ ๋๋ ค ํธ๋ค.
- ์ผ์์ ๊ฒฐํฉ์ ์ถ์ํ๊ธฐ ๋๋ฌธ์ ๊ฐ๋ฐ์๋ ๋ ์ด์ ์ ๊ฒฝ ์ธ ํ์๊ฐ ์๋ค.
- ์ฌ๋ฌ ์ฝ๋ฐฑ ๋์ , ๋จ์ผ ํจ์๋ก ์๋ฌ ์ฒ๋ฆฌ ๋ก์ง์ ํตํฉํ์ฌ ์ฝ๋ ํ๋ฆ์ ์ํ ํ๊ฒ ํ๋ค.
- ๋ชจ๋๋์๋ ํ๋ผ๋ฏธ์ค(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 ๊ฐ์ฒด์ ์์ฑ์ ๋ค์๊ณผ ๊ฐ๋ค.
done
: ์ ์ผ ๋ง์ง๋ง์ ์ดํฐ๋ ์ดํฐ๊ฐ ์ ๋ฌ๋๋ฉดtrue
, ๊ทธ ์ธ์๋false
๋ก ์ธํ ๋๋ค. ์ฆ,false
๋ ์ดํฐ๋ ์ดํฐ๊ฐ ์์ง ๋์ค์ ๋ค๋ฅธ ๊ฐ์ ์์ฐํ ์ ์์์ ์๋ฏธํ๋ค.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++ };
}
};
}