11. Things you can already do
alt: S*#t that annoys Jan in JavaScript
12. NodeList is not an array
1 document.querySelectorAll('li')
2 .filter(function(li) {
3 /* do something */
4 });
5
ERROR: document.querySelectorAll(...).filter
is not a function
13. NodeList is not an array
1 Array.prototype.slice.call(
2 document.querySelectorAll('li')
3 )
14. NodeList is not an array
1 Array.prototype.slice.call(
2 document.querySelectorAll('li')
3 )
1 Array.from(
2 document.querySelectorAll('li')
3 )
15. Variable scoping
1 var a = 7;
2
3 if (something) {
4 var a = 9;
5 doSomethingElse(a);
6 }
7
8 console.log(a);
16. Variable scoping
1 var a = 7;
2
3 if (something) {
4 var a = 9;
5 doSomethingElse(a);
6 }
7
8 console.log(a);
// can be 7 or 9 depending on 'something'
17. Variable scoping
1 var a = 7;
2
3 if (something) {
4 var a = 9;
5 doSomethingElse(a);
6 }
7
8 console.log(a);
// can be 7 or 9 depending on 'something'
18. Variable scoping
1 var a = 7;
2
3 if (something) {
4 var a = 9;
5 doSomethingElse(a);
6 }
7
8 console.log(a);
// can be 7 or 9 depending on 'something'
19. Variable scoping
1 let a = 7;
2
3 if (something) {
4 let a = 9;
5 doSomethingElse(a);
6 }
7
8 console.log(a);
// always 7
‘let’ to the rescue
20. Variable scoping
1 let a = 7;
2
3 if (something) {
4 let a = 9;
5 doSomethingElse(a);
6 }
7
8 console.log(a);
// always 7
‘let’ to the rescue
87. Normal function
1 function normal() {
2 console.log('Hi there!');
3
4 var a = 5 + 6;
5 console.log('I think it's', a);
6
7 console.log('kthxbye');
8
9 return 3;
10 }
88. Generators are lazy
1 function* turingWinners () {
2 console.log('Hello from our function');
3 yield "Alan J. Perlis";
4 console.log('I returned the first one');
5 yield "Maurice Wilkes";
6 yield "Richard Hamming";
7 yield "Marvin Minsky";
8 }
9
10 turingWinners();
89. Generators are lazy
1 function* turingWinners () {
2 console.log('Hello from our function');
3 yield "Alan J. Perlis";
4 console.log('I returned the first one');
5 yield "Maurice Wilkes";
6 yield "Richard Hamming";
7 yield "Marvin Minsky";
8 }
9
10 turingWinners();
90. Generators are lazy
1 function* turingWinners () {
2 console.log('Hello from our function');
3 yield "Alan J. Perlis";
4 console.log('I returned the first one');
5 yield "Maurice Wilkes";
6 yield "Richard Hamming";
7 yield "Marvin Minsky";
8 }
9
10 turingWinners();
91. Generators are lazy
1 function* turingWinners () {
2 console.log('Hello from our function');
3 yield "Alan J. Perlis";
4 console.log('I returned the first one');
5 yield "Maurice Wilkes";
6 yield "Richard Hamming";
7 yield "Marvin Minsky";
8 }
9
10 turingWinners();
92. Generators are lazy
1 function* turingWinners () {
2 console.log('Hello from our function');
3 yield "Alan J. Perlis";
4 console.log('I returned the first one');
5 yield "Maurice Wilkes";
6 yield "Richard Hamming";
7 yield "Marvin Minsky";
8 }
9
10 turingWinners();
$ node --harmony test.js
$
93. Call next() to start
1 function* turingWinners () {
2 console.log('Hello from our function');
3 yield "Alan J. Perlis";
4 console.log('I returned the first one');
5 yield "Maurice Wilkes";
6 yield "Richard Hamming";
7 yield "Marvin Minsky";
8 }
9
10 var iterator = turingWinners();
11
12 console.log(iterator.next());
13 console.log(iterator.next());
94. Call next() to start
1 function* turingWinners () {
2 console.log('Hello from our function');
3 yield "Alan J. Perlis";
4 console.log('I returned the first one');
5 yield "Maurice Wilkes";
6 yield "Richard Hamming";
7 yield "Marvin Minsky";
8 }
9
10 var iterator = turingWinners();
11
12 console.log(iterator.next());
13 console.log(iterator.next());
95. Call next() to start
1 function* turingWinners () {
2 console.log('Hello from our function');
3 yield "Alan J. Perlis";
4 console.log('I returned the first one');
5 yield "Maurice Wilkes";
6 yield "Richard Hamming";
7 yield "Marvin Minsky";
8 }
9
10 var iterator = turingWinners();
11
12 console.log(iterator.next());
13 console.log(iterator.next());
96. Call next() to start
1 function* turingWinners () {
2 console.log('Hello from our function');
3 yield "Alan J. Perlis";
4 console.log('I returned the first one');
5 yield "Maurice Wilkes";
6 yield "Richard Hamming";
7 yield "Marvin Minsky";
8 }
9
10 var iterator = turingWinners();
11
12 console.log(iterator.next());
13 console.log(iterator.next());
$ node --harmony test.js
Hello from our function
{ value: 'Alan J. Perlis', done: false }
97. Call next() to start
1 function* turingWinners () {
2 console.log('Hello from our function');
3 yield "Alan J. Perlis";
4 console.log('I returned the first one');
5 yield "Maurice Wilkes";
6 yield "Richard Hamming";
7 yield "Marvin Minsky";
8 }
9
10 var iterator = turingWinners();
11
12 console.log(iterator.next());
13 console.log(iterator.next());
98. Call next() to start
1 function* turingWinners () {
2 console.log('Hello from our function');
3 yield "Alan J. Perlis";
4 console.log('I returned the first one');
5 yield "Maurice Wilkes";
6 yield "Richard Hamming";
7 yield "Marvin Minsky";
8 }
9
10 var iterator = turingWinners();
11
12 console.log(iterator.next());
13 console.log(iterator.next());
99. Call next() to start
1 function* turingWinners () {
2 console.log('Hello from our function');
3 yield "Alan J. Perlis";
4 console.log('I returned the first one');
5 yield "Maurice Wilkes";
6 yield "Richard Hamming";
7 yield "Marvin Minsky";
8 }
9
10 var iterator = turingWinners();
11
12 console.log(iterator.next());
13 console.log(iterator.next());
$ node --harmony test.js
Hello from our function
{ value: 'Alan J. Perlis', done: false }
I returned the first one
{ value: 'Maurice Wilkes', done: false }
100. Inef!cient thing in JS
1 var nice = [1,2,3,4,5,6,7,8,9,10,11,12]
2 .filter(function(v) {
3 return v % 2 === 0;
4 })
5 .map(function(v) {
6 return v * v;
7 })
8 .slice(0, 3);
9
10 console.log(nice);
101. Inef!cient thing in JS
1 var nice = [1,2,3,4,5,6,7,8,9,10,11,12]
2 .filter(function(v) {
3 return v % 2 === 0;
4 })
5 .map(function(v) {
6 return v * v;
7 })
8 .slice(0, 3);
9
10 console.log(nice);
102. Inef!cient thing in JS
1 var nice = [1,2,3,4,5,6,7,8,9,10,11,12]
2 .filter(function(v) {
3 return v % 2 === 0;
4 })
5 .map(function(v) {
6 return v * v;
7 })
8 .slice(0, 3);
9
10 console.log(nice);
103. Inef!cient thing in JS
1 var nice = [1,2,3,4,5,6,7,8,9,10,11,12]
2 .filter(function(v) {
3 return v % 2 === 0;
4 })
5 .map(function(v) {
6 return v * v;
7 })
8 .slice(0, 3);
9
10 console.log(nice);
104. Inef!cient thing in JS
1 var nice = [1,2,3,4,5,6,7,8,9,10,11,12]
2 .filter(function(v) {
3 return v % 2 === 0;
4 })
5 .map(function(v) {
6 return v * v;
7 })
8 .slice(0, 3);
9
10 console.log(nice);
105. 1 function* generateNumber() {
2 var i = 0;
3 while (true)
4 yield ++i;
5 }
6
7 function* filter(it) {
8 for (var n of it)
9 if (n % 2 == 0) yield curr;
10 }
11
12 function* map(it) {
13 for (var n of it)
14 yield n * n;
15 }
106. 1 function* generateNumber() {
2 var i = 0;
3 while (true)
4 yield ++i;
5 }
6
7 function* filter(it) {
8 for (var n of it)
9 if (n % 2 == 0) yield curr;
10 }
11
12 function* map(it) {
13 for (var n of it)
14 yield n * n;
15 }
107. 1 function* generateNumber() {
2 var i = 0;
3 while (true)
4 yield ++i;
5 }
6
7 function* filter(it) {
8 for (var n of it)
9 if (n % 2 == 0) yield curr;
10 }
11
12 function* map(it) {
13 for (var n of it)
14 yield n * n;
15 }
1,2,3,4,5,6
108. 1 function* generateNumber() {
2 var i = 0;
3 while (true)
4 yield ++i;
5 }
6
7 function* filter(it) {
8 for (var n of it)
9 if (n % 2 == 0) yield curr;
10 }
11
12 function* map(it) {
13 for (var n of it)
14 yield n * n;
15 }
1,2,3,4,5,6
109. 1 function* generateNumber() {
2 var i = 0;
3 while (true)
4 yield ++i;
5 }
6
7 function* filter(it) {
8 for (var n of it)
9 if (n % 2 == 0) yield curr;
10 }
11
12 function* map(it) {
13 for (var n of it)
14 yield n * n;
15 }
1,2,3,4,5,6
n%2 == 0
2,4,6
110. 1 function* generateNumber() {
2 var i = 0;
3 while (true)
4 yield ++i;
5 }
6
7 function* filter(it) {
8 for (var n of it)
9 if (n % 2 == 0) yield curr;
10 }
11
12 function* map(it) {
13 for (var n of it)
14 yield n * n;
15 }
1,2,3,4,5,6
n%2 == 0
2,4,6
111. 1 function* generateNumber() {
2 var i = 0;
3 while (true)
4 yield ++i;
5 }
6
7 function* filter(it) {
8 for (var n of it)
9 if (n % 2 == 0) yield curr;
10 }
11
12 function* map(it) {
13 for (var n of it)
14 yield n * n;
15 }
1,2,3,4,5,6
n%2 == 0
2,4,6
n * n
4,16,36
112. Using the generators
1 var nice = generateNumber();
2 nice = filter(nice);
3 nice = map(nice);
4
5 for (var i = 0; i < 3; i++) {
6 console.log(i, nice.next().value);
7 }
113. Using the generators
1 var nice = generateNumber();
2 nice = filter(nice);
3 nice = map(nice);
4
5 for (var i = 0; i < 3; i++) {
6 console.log(i, nice.next().value);
7 }
114.
115. Two way interaction
1 function* printName() {
2 var name = yield 'Whats your name?';
3 console.log('Hello', name);
4 }
5
6 var iterator = printName();
7 console.log('It:', iterator.next().value);
8
9 setTimeout(function() {
10 var ret = iterator.next('Jan Jongboom');
11 console.log(ret);
12 }, 1000);
116. Two way interaction
1 function* printName() {
2 var name = yield 'Whats your name?';
3 console.log('Hello', name);
4 }
5
6 var iterator = printName();
7 console.log('It:', iterator.next().value);
8
9 setTimeout(function() {
10 var ret = iterator.next('Jan Jongboom');
11 console.log(ret);
12 }, 1000);
117. Two way interaction
1 function* printName() {
2 var name = yield 'Whats your name?';
3 console.log('Hello', name);
4 }
5
6 var iterator = printName();
7 console.log('It:', iterator.next().value);
8
9 setTimeout(function() {
10 var ret = iterator.next('Jan Jongboom');
11 console.log(ret);
12 }, 1000);
118. Two way interaction
1 function* printName() {
2 var name = yield 'Whats your name?';
3 console.log('Hello', name);
4 }
5
6 var iterator = printName();
7 console.log('It:', iterator.next().value);
8
9 setTimeout(function() {
10 var ret = iterator.next('Jan Jongboom');
11 console.log(ret);
12 }, 1000);
119. Two way interaction
1 function* printName() {
2 var name = yield 'Whats your name?';
3 console.log('Hello', name);
4 }
5
6 var iterator = printName();
7 console.log('It:', iterator.next().value);
8
9 setTimeout(function() {
10 var ret = iterator.next('Jan Jongboom');
11 console.log(ret);
12 }, 1000);
120. Two way interaction
1 function* printName() {
2 var name = yield 'Whats your name?';
3 console.log('Hello', name);
4 }
5
6 var iterator = printName();
7 console.log('It:', iterator.next().value);
8
9 setTimeout(function() {
10 var ret = iterator.next('Jan Jongboom');
11 console.log(ret);
12 }, 1000);
121. Two way interaction
1 function* printName() {
2 var name = yield 'Whats your name?';
3 console.log('Hello', name);
4 }
5
6 var iterator = printName();
7 console.log('It:', iterator.next().value);
8
9 setTimeout(function() {
10 var ret = iterator.next('Jan Jongboom');
11 console.log(ret);
12 }, 1000);
$ node --harmony test.js
It: Whats your name?
122. Two way interaction
1 function* printName() {
2 var name = yield 'Whats your name?';
3 console.log('Hello', name);
4 }
5
6 var iterator = printName();
7 console.log('It:', iterator.next().value);
8
9 setTimeout(function() {
10 var ret = iterator.next('Jan Jongboom');
11 console.log(ret);
12 }, 1000);
$ node --harmony test.js
It: Whats your name?
$ node --harmony test.js
It: Whats your name?
Hello Jan Jongboom
{ value: undefined, done: true }
123. Yield and deferred values
• Wrote sync code
• But yield waits until new value comes in...
• So it’s actually async with sync syntax
• We need to abuse this!
1 function* printName() {
2 var name = yield 'Whats your name?';
3 console.log('Hello', name);
4 }
124. 1 function* run() {
2 yield sleep(2000);
3 console.log('It has been 2 seconds');
4 }
5
6 function sleep(ms) {
7 return new Promise((res, rej) => {
8 setTimeout(res, ms);
9 });
10 }
11
12 var it = run();
13 var ret = it.next().value;
14
15 ret.then(function() {
16 it.next();
17 });
125. 1 function* run() {
2 yield sleep(2000);
3 console.log('It has been 2 seconds');
4 }
5
6 function sleep(ms) {
7 return new Promise((res, rej) => {
8 setTimeout(res, ms);
9 });
10 }
11
12 var it = run();
13 var ret = it.next().value;
14
15 ret.then(function() {
16 it.next();
17 });
126. 1 function* run() {
2 yield sleep(2000);
3 console.log('It has been 2 seconds');
4 }
5
6 function sleep(ms) {
7 return new Promise((res, rej) => {
8 setTimeout(res, ms);
9 });
10 }
11
12 var it = run();
13 var ret = it.next().value;
14
15 ret.then(function() {
16 it.next();
17 });
127. 1 function* run() {
2 yield sleep(2000);
3 console.log('It has been 2 seconds');
4 }
5
6 function sleep(ms) {
7 return new Promise((res, rej) => {
8 setTimeout(res, ms);
9 });
10 }
11
12 var it = run();
13 var ret = it.next().value;
14
15 ret.then(function() {
16 it.next();
17 });
128. 1 function* run() {
2 yield sleep(2000);
3 console.log('It has been 2 seconds');
4 }
5
6 function sleep(ms) {
7 return new Promise((res, rej) => {
8 setTimeout(res, ms);
9 });
10 }
11
12 var it = run();
13 var ret = it.next().value;
14
15 ret.then(function() {
16 it.next();
17 });
129. 1 function* run() {
2 yield sleep(2000);
3 console.log('It has been 2 seconds');
4 }
5
6 function sleep(ms) {
7 return new Promise((res, rej) => {
8 setTimeout(res, ms);
9 });
10 }
11
12 var it = run();
13 var ret = it.next().value;
14
15 ret.then(function() {
16 it.next();
17 });
130. 1 function* run() {
2 yield sleep(2000);
3 console.log('It has been 2 seconds');
4 }
5
6 function sleep(ms) {
7 return new Promise((res, rej) => {
8 setTimeout(res, ms);
9 });
10 }
11
12 var it = run();
13 var ret = it.next().value;
14
15 ret.then(function() {
16 it.next();
17 });
131. 1 function* run() {
2 yield sleep(2000);
3 console.log('It has been 2 seconds');
4 }
5
6 function sleep(ms) {
7 return new Promise((res, rej) => {
8 setTimeout(res, ms);
9 });
10 }
11
12 var it = run();
13 var ret = it.next().value;
14
15 ret.then(function() {
16 it.next();
17 });
132. 1 function* run() {
2 yield sleep(2000);
3 console.log('It has been 2 seconds');
4 }
5
6 function sleep(ms) {
7 return new Promise((res, rej) => {
8 setTimeout(res, ms);
9 });
10 }
11
12 var it = run();
13 var ret = it.next().value;
14
15 ret.then(function() {
16 it.next();
17 });