Name | URL |
---|---|
holee | |
sunpark | |
dongbkim | |
gim | |
sohpark | |
nkang | |
yujo |
dongbkim
- ๋ค์ ์ฝ๋์ ๊ฒฐ๊ณผ๋ฅผ ์์ธกํ๊ณ ๋ฒ๊ทธ๊ฐ ์๋ค๋ฉด ๊ณ ์น์์ค.
(1)
function *foo(){
yield 1;
yield 2;
yield 3;
return 5;
}
var it = foo();
while(it.done != true)
{
console.log(it.next());
}
(2)
let x = 1;
let y = 10;
function *bar(){
x--;
x = (yield x) + y;
yield;
x += 10;
x *= (yield 2);
}
function *baz(){
var b = (yield 1);
y = (yield b) + x;
y += (yield 1);
x -= yield 20;
console.log(x + y);
}
function step(gen){
var it = gen();
var last;
return function go(){
last = it.next(last).value;
};
}
var s1 = step(bar);
var s2 = step(baz);
s1();
s1();
s2();
s1();
s2();
s2();
s1();
s2();
s2();
(3)
let x = 1;
let y = 10;
function *bar(){
x--;
x = (yield x) + y;
yield;
x += 10;
x *= (yield 2);
x--;
}
function *baz(){
var b = (yield 1);
y = (yield b) + x;
y += (yield 1);
x -= yield 20;
console.log(x + y);
}
function step(gen){
var it = gen();
return function go(){
var last = it.next(1).value;
};
}
var s1 = step(bar);
var s2 = step(baz);
s1();
s1();
s2();
s1();
s2();
s2();
s1();
s2();
s2();
๐ ๋ต์ง
{ value: 1, done: false }
{ value: 2, done: false }
{ value: 3, done: false }
{ value: 5, done: true }
{ value: undefined, done: true }
{ value: undefined, done: true }
{ value: undefined, done: true }
.
.
.
๊ณ ์น ์ฝ๋
function *foo(){
yield 1;
yield 2;
yield 3;
return 5;
}
var it = foo();
// var buf = it.next();
// console.log(buf);
// while(buf.done !== true)
// {
// buf = it.next();
// console.log(buf);
// }
var buf;
do {
buf = it.next();
console.log(buf);
} while(buf.done !== true);
(2) 42
(3) 42
gim
- ___ ๋ producer๋ก์ ์ด์ ์ ๊ฐ๊ณผ ์ฐ๊ด๋ ๊ฐ์ ์ฐ์์ ์ผ๋ก ์ ๊ณตํ๋ค. ์ด๋ ์ธ๋ถ์์ ํด๋น ์ค์ฝํ์ ๊ฐ์ ์ฐธ์กฐํ๋ ๊ฐ๋ ์ธ ___ ๋ฅผ ์ฐจ์ฉํ๊ธฐ ๋๋ฌธ์ ๊ฐ๋ฅํ ๋์์ธ ํจํด์ด๋ค.
- producer์์ ์ ๊ณตํ ๊ฐ์ ๋จ๊ณ์ ์ผ๋ก ์ฒ๋ฆฌํ๊ธฐ ์ํด ๊ฐ์ฅ ์ ํฉํ ์ธํฐํ์ด์ค๋ ___ ๋ผ๊ณ ํ ์ ์๋ค.
for..of
๊ตฌ๋ฌธ์ ๋์ ๋ฐฉ์
- ์ฐธ์กฐํ๋ ค๋ ๊ฐ์ฒด๊ฐ ___ ์ธ์ง ํ์ธํ๋ค.
- ํด๋น ๊ฐ์ฒด์ ___ ๋ฉ์๋๋ฅผ ์๋์ผ๋ก ํธ์ถํ๋ค.
- ์ ๋ฉ์๋๋ก ๋ฐํ๋ ___ ๊ฐ์ฒด์ ___ ๋ฉ์๋๋ฅผ ๋ฐ๋ณต์ ์ผ๋ก ํธ์ถํ์ฌ ํด๋น value๋ฅผ ์ฐธ์กฐํ๋ค.
- generator function ๋ํ
for..of
๋ฌธ์ ํตํด ์ฐ์์ ์ธ ๊ฐ์ ์ฐธ์กฐํ ์ ์๋ค. ํ์ง๋ง ์ง์ ํธ์ถ์ ํด์ฃผ์ด์ผ ํ๋๋ฐ, ๊ทธ ์ด์ ๋ ๋ฌด์์ผ๊น?
for (let value of generator()) { // why?
logic...
}
- generator ์ iterator ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ๋
for..of
๊ตฌ๋ฌธ์์break
๋ฅผ ์ฌ์ฉํ ์ข ๋ฃ๋ ํด๋น ๊ฐ์ฒด์ ๋ํ ๋ถ์์ ํ ์๊ฒฐ์ฑ์ ๊ฐ์ง๋ค. ๊ทธ๋ ๊ธฐ์ ์ฌ์ฉ์ ์ธก๋ฉด์์ ์๊ฒฐ์ฑ์ ์ ์ดํ๊ธฐ ์ํด ___ ๊ตฌ๋ฌธ๊ณผ iterator ๊ฐ์ฒด์ ___ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
๐ ๋ต์ง
- Generator / Closure
- Iterator
- iterable /
Symbol.iterator
/ iterator /next
for..of
๋ iterable์ ํ์๋ก ํ๋ค. generator function ์์ ๋ฐํ๋ iterator ๊ฐ์ฒด๋Symbol.iterator
์next
๋ฅผ ๋ชจ๋ ๊ฐ์ง๊ณ ์๊ธฐ ๋๋ฌธ์ iterable ์ด๋ฉด์ iterator ๋ผ๊ณ ๋ณธ๋ค.try..finally
/return
gim
- ๊ธฐ์กด์ ์ฝ๋ฐฑ์ ์ฌ์ฉํ ๋น๋๊ธฐ ์ฒ๋ฆฌ์ ๋น๊ตํ์ ๋, ๋ค์ ์ฝ๋๋ก ์ป์ ์ ์๋ ์ด์ ์ ๋ํด ์ด์ผ๊ธฐ ํด๋ด ์๋ค.
function foo() {
ajax(url, (err, data) => {
if (err) {
it.throw(err);
} else {
it.next(data);
}
});
}
function* main() {
try {
var text = yield foo();
console.log(text);
} catch (err) {
console.error(err);
}
}
var it = main();
it.next();
๐ ๋ต์ง
- async-await ์
await
๊ด์ ์ผ๋ก ๋ณด๋ฉด ์ข ๋ ์ดํด ํ๊ธฐ ํธํ๋ค.it.next()
๋ฅผ ํธ์ถ ํ๋ฉด ๋งจ ์ฒ์yield
์ง์ ์foo()
๋ฅผ ํธ์ถ.foo()
์ ๋น๋๊ธฐ ์ฒ๋ฆฌ๊ฐ ๋๋ ๋๊น์ง*main
์ ํ์์ ๋ก์ง์ ๊ธฐ๋ค๋ฆฐ๋ค.ajax()
์์ ๋ฐ์์จ ๋ฐ์ดํฐ๋ฅผ ํ๋จํ์ฌit
๊ฐ์ฒด์ ๋ฉ์๋๋ฅผ ํธ์ถํ๊ณ ๊ทธ์ ๋ํ ์ฒ๋ฆฌ๋*main
์์ ์ํํ๋ค.
์ด์ ๊ฐ์ ํ๋ฆ์ผ๋ก 'ajax ์์ฒญ -> ๋ฐ์ดํฐ ์ฒ๋ฆฌ' ์ ๋๊ธฐ(์ฒ๋ผ ๋ณด์ด๋) ์ฒ๋ฆฌ๊ฐ ๊ฐ๋ฅํ๋ค.
sohpark
- ๋ค์๊ณผ ๊ฐ์ ํ๋ผ๋ฏธ์ค๋ฅผ ๋ฐํํ๋ ํจ์์ ์ ๋ค๋ ์ดํฐ๊ฐ ์ ์๋์ด ์์ ๋,
Hello World
๋ฅผ ์ถ๋ ฅํ๊ฒ ํ๋ ค๋ฉด ์ด๋ป๊ฒ ํด์ผํ ์ง then์ ์ด์ฉํ์ฌ ์ฝ๋๋ฅผ ์์ฑํด์ฃผ์ธ์.
function apiCall(x) {
return Promise.resolve(x); // ๋น๋๊ธฐ ํจ์. Promise ๋ฐํ
}
function* main() {
try {
let result = yield apiCall('Hello World');
console.log(result);
} catch (err) {
console.error(err);
}
}
- ๋ค์ ์ฝ๋๋ฅผ ๋ณด๊ณ ๋์ฌ ์ ์๋ ์ด์ผ๊ธฐ ์ค ์ณ์ง ์์ ๊ฒ์?
function apiCall(x) {
return Promise.resolve(x); // ๋น๋๊ธฐ ํจ์. Promise ๋ฐํ
}
function* gen() {
let val1 = yield apicall('someurl01');
let val2 = yield apicall('someurl02');
let val3 = yield apicall('someurl' + val1 + val2);
console.log(val3);
}
run(gen);
- run ํจ์๋ ์ธ์๋ก ๋ฐ์ ์ ๋ค๋ฆฌ์ดํฐ ์์์ promise๋ฅผ yield ํ๋ฉด resolve๋ ๊ฐ์ ๋ฐํํ๊ฒ๋ ๋์์ฃผ๋ ํจ์์ด๋ค.
- genํจ์๊ฐ ์ ๋ค๋ ์ดํฐ๊ฐ ์๋๋ผ๋ฉด yield๋์ await๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ด ์๋ค.
- ์ ๋ค๋ฆฌ์ดํฐ ํน์ฑ์ val1, val2๋ ๋ณ๋ ฌ ์์ ์ด ๋ถ๊ฐ๋ฅํ๋ค.
๐ ๋ต์ง
let it = main();
let p = it.next().value;
p.then(
res => {
it.next(res);
},
err => {
it.throw(err);
}
);
์ ๋ค๋ฆฌ์ดํฐ ํจ์์ ํน์ฑ์ val1, val2๋ ๋ณ๋ ฌ ์์ ์ด ๋ถ๊ฐ๋ฅํ๋ค.
๋ ์๋ชป๋ ๋ง๋ก, val1๊ณผ val2๋ฅผ ์ป์ด์ค๋ Promise๋ ๋ณ๋ ฌ์ ์ผ๋ก ์์ ์ด ๊ฐ๋ฅํ๋ค. yield์ Promise.all์ ์ด์ฉํ๋ ๋ฐฉ๋ฒ์ด ์๋๋ฐ, ์ฑ ์์ ์๊ฐ๋ ๋ฐฉ๋ฒ๋ค์ ์๋์ ๊ฐ๋ค.
function* gen() {
let p1 = apicall('someurl01');
let p2 = apicall('someurl02');
let val1 = yield p1;
let val2 = yield p2;
let val3 = yield apicall('someurl' + val1 + val2);
console.log(val3);
}
function* gen() {
let vals = yield Promise.all([apicall('someurl01'), apicall('someurl02')]);
let [val1, val2] = vals;
let val3 = yield apicall('someurl' + val1 + val2);
console.log(val3);
}
nkang
๋ค์ ์ฝ๋์ ์คํ ๊ฒฐ๊ณผ๋ฅผ ์ฐ์์ค.
function *innerGenerator() {
yield *['a', 'b', 'c'];
}
function *generator() {
yield *[1, 2, 3];
const innerGen = innerGenerator();
console.log(innerGen);
yield *innerGenerator();
}
[...generator()];
๐ ๋ต์ง
Iterator [Generator] {}
[ 1, 2, 3, 'a', 'b', 'c' ]
์ ๋๋ ์ดํฐ๋ yield *
๋ฅผ ํตํ์ฌ ๋ค๋ฅธ ์ ๋๋ ์ดํฐ ํจ์๋ฅผ ์คํํ ์ ์๋ค. innerGeneration๋ฅผ ํธ์ถํ๋ฉด ์ดํฐ๋ ์ดํฐ ๊ฐ์ฒด๊ฐ ๋ฐํ๋์ง๋ง ์ค์ ๋ก innerGenerator๊ฐ ์คํ๋์ง๋ ์๋๋ค.
(yield-delegation doesn't even have to be directed to another generator; it can just be directed to a non-generator, general iterable.)
yujo
- ๋ค์ ์ฝ๋์์ console์ true๊ฐ ์ถ๋ ฅ๋๋ ๊ณณ์ ์ด๋์ผ๊น์?
const res = [];
function* foo() {
var random = Math.random();
yield;
res.push(random);
}
const it = foo();
console.log(Boolean(res.length)); // (1)
it.next();
console.log(Boolean(res.length)); // (2)
it.next();
console.log(Boolean(res.length)); // (3)
it.next();
console.log(Boolean(res.length)); // (4)
๐ ๋ต์ง
(3), (4)
yujo
- ๋น๋๊ธฐ ํจํด์์ Thunks๋ฅผ Promise ๋์ ์ฌ์ฉํ๋ ๊ฒ์ ๊ถ์ฅํ๋ค. (O / X)
- Thunk๋ฅผ ๊ฐ๋จํ๊ฒ ์ค๋ช ํด์ฃผ์ธ์.
๐ ๋ต์ง
1.X
Thunk๋ Prmise์ ๋ฏฟ์์ฑ/์กฐํฉ์ฑ์ ๋ณด์ฅํ์ง ๋ชป ํ๋ค.
2. ๋ค๋ฅธ ํจ์๋ฅผ ํธ์ถํ ์ด๋ช
์ ๊ฐ์ง ์ธ์๊ฐ ์๋ ํจ์, Thunk์์๋ ๋ฐ์ fooThunk()
function foo(x, y) {
return x + y;
}
function fooThunk() {
return foo(3, 4)
}
holee
-
Generator์ ES5 polyfill์ ์ํ ์ ๋ช ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ค facebook์ด ๋ง๋ (___________)๊ฐ ์๋ค.
-
๋ค์์ Generator polyfill ์ฝ๋์ ์ผ๋ถ์ด๋ค. ๋น์นธ์ ๋ค์ด๊ฐ ๋ณ์์ ๊ธฐ๋ฅ์ ์ค๋ช ํ๋ผ.
function foo(url) {
...
return {
next: function(v) {
if (!__blank__) {
__blank__ = 1;
return {
done: false,
value: process()
};
}
else if (__blank__ == 1) {
__blank__ = 2;
return {
done: true,
value: process( v )
};
}
...
}
๐ ๋ต์ง
-
Generator์ ES5 polyfill์ ์ํ ์ ๋ช ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ค facebook์ด ๋ง๋ (regenerator)๊ฐ ์๋ค.
-
๋ค์์ Generator polyfill ์ฝ๋์ ์ผ๋ถ์ด๋ค. ๋น์นธ์ ๋ค์ด๊ฐ ๋ณ์์ ๊ธฐ๋ฅ์ ์ค๋ช ํ๋ผ.
function foo(url) {
// manage generator state
var state;
// generator-wide variable declarations
var val;
function process(v) {
switch (state) {
case 1:
console.log( "requesting:", url );
return request( url );
case 2:
val = v;
console.log( val );
return;
case 3:
var err = v;
console.log( "Oops:", err );
return false;
}
}
// make and return an iterator
return {
next: function(v) {
// initial state
if (!state) {
state = 1;
return {
done: false,
value: process()
};
}
// yield resumed successfully
else if (state == 1) {
state = 2;
return {
done: true,
value: process( v )
};
}
// generator already completed
else {
return {
done: true,
value: undefined
};
}
},
"throw": function(e) {
// the only explicit error handling is in
// state *1*
if (state == 1) {
state = 3;
return {
done: true,
value: process( e )
};
}
// otherwise, an error won't be handled,
// so just throw it right back out
else {
throw e;
}
}
};
}