ES.next for humans
@janjongboom
LvivJS 2014
@janjongboom
@janjongboom
I hate
JavaScript!
VBScript
<3 <3 <3
програма
Things you could already do
Things you needed a framework for
Things that were impossible
Things you can already do
alt: S*#t that annoys Jan in JavaScript
NodeList is not an array
1 document.querySelectorAll('li')
2 .filter(function(li) {
3 /* do something */
4 });
5
ERROR: do...
NodeList is not an array
1 Array.prototype.slice.call(
2 document.querySelectorAll('li')
3 )
NodeList is not an array
1 Array.prototype.slice.call(
2 document.querySelectorAll('li')
3 )
1 Array.from(
2 document.quer...
Variable scoping
1 var a = 7;
2
3 if (something) {
4 var a = 9;
5 doSomethingElse(a);
6 }
7
8 console.log(a);
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 ...
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 ...
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 ...
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
...
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
...
Tuples
Multiple return values
1 function getPosition() {
2 return [ 12, 91 ];
3 }
4
5 var pos = getPosition();
6 var x = pos[0],
7 y = pos[1];
8
9 funct...
1 function getPosition() {
2 return [ 12, 91 ];
3 }
4
5 var pos = getPosition();
6 var x = pos[0],
7 y = pos[1];
8
9 funct...
1 function getPosition() {
2 return [ 12, 91 ];
3 }
4
5 var pos = getPosition();
6 var x = pos[0],
7 y = pos[1];
8
9 funct...
1 var data = {};
2
3 data['jan'] = 'awesome';
4 data['pete'] = 'not so awesome';
5
6 var ele1 = document.querySelector('#e...
1 var data = {};
2
3 data['jan'] = 'awesome';
4 data['pete'] = 'not so awesome';
5
6 var ele1 = document.querySelector('#e...
1 var data = {};
2
3 data['jan'] = 'awesome';
4 data['pete'] = 'not so awesome';
5
6 var ele1 = document.querySelector('#e...
1 var data = {};
2
3 data['jan'] = 'awesome';
4 data['pete'] = 'not so awesome';
5
6 var ele1 = document.querySelector('#e...
Maps
1 var data = {};
2
3 data['jan'] = 'awesome';
4 data['pete'] = 'not so awesome';
5
6 var ele1 = document.querySelecto...
Maps
1 var data = {};
2
3 data['jan'] = 'awesome';
4 data['pete'] = 'not so awesome';
5
6 var ele1 = document.querySelecto...
Maps
1 var data = new Map();
2
3 data.set('jan', 'awesome');
4
5 data.has('jan'); // true
6 data.get('jan'); // "awesome"
...
Maps
1 var data = new Map();
2
3 data.set('jan', 'awesome');
4
5 data.has('jan'); // true
6 data.get('jan'); // "awesome"
...
Function boilerplate
1
2 someArray
3 .filter(function(item) {
4 return item.isActive;
5 })
6 .map(function(item) {
7 retur...
Function boilerplate
1
2 someArray
3 .filter(function(item) {
4 return item.isActive;
5 })
6 .map(function(item) {
7 retur...
Function boilerplate
1
2 someArray
3 .filter(function(item) {
4 return item.isActive;
5 })
6 .map(function(item) {
7 retur...
Function boilerplate
1
2 someArray
3 .filter(function(item) {
4 return item.isActive;
5 })
6 .map(function(item) {
7 retur...
Things you need a
framework for
a.k.a. Goodbye Angular!
Promises
1 new Promise(function(resolve, reject) {
2 resolve('Success!');
3 // or...
4 reject('I failed!');
5 });
Native promises
Data binding
AngularJS
1 function SomeCtrl() {
2 $scope.name = "Jan";
3 }
1 <div ng-controller="SomeCtrl">
2 <input type="text" ng-mode...
Now without
a framework
From JS -> HTML
1 <div>
2 <input type="text" data-bind="name">
3 Hello <span data-bind="name"></span>
4 </div>
1 var scope...
From JS -> HTML
1 <div>
2 <input type="text" data-bind="name">
3 Hello <span data-bind="name"></span>
4 </div>
1 var scope...
From JS -> HTML
1 <div>
2 <input type="text" data-bind="name">
3 Hello <span data-bind="name"></span>
4 </div>
1 var scope...
1 function updateScope() {
2 var els = document.querySelectorAll(
3 '*[data-bind=name]'
4 );
5
6 Array.from(els).forEach(f...
1 function updateScope() {
2 var els = document.querySelectorAll(
3 '*[data-bind=name]'
4 );
5
6 Array.from(els).forEach(f...
1 function updateScope() {
2 var els = document.querySelectorAll(
3 '*[data-bind=name]'
4 );
5
6 Array.from(els).forEach(f...
1 function updateScope() {
2 var els = document.querySelectorAll(
3 '*[data-bind=name]'
4 );
5
6 Array.from(els).forEach(f...
1 function updateScope() {
2 var els = document.querySelectorAll(
3 '*[data-bind=name]'
4 );
5
6 Array.from(els).forEach(f...
But what if we change
scope.name from JS?
1 Object.observe(scope, function(changes) {
2 changes.forEach(function(change) {
3 if (change.type === 'update' &&
4 chang...
1 Object.observe(scope, function(changes) {
2 changes.forEach(function(change) {
3 if (change.type === 'update' &&
4 chang...
1 Object.observe(scope, function(changes) {
2 changes.forEach(function(change) {
3 if (change.type === 'update' &&
4 chang...
1 Object.observe(scope, function(changes) {
2 changes.forEach(function(change) {
3 if (change.type === 'update' &&
4 chang...
From HTML -> JS (1)
1 var els = document.querySelectorAll(
2 '*[data-bind=name]'
3 );
4
5 var observer = new MutationObser...
From HTML -> JS (1)
1 var els = document.querySelectorAll(
2 '*[data-bind=name]'
3 );
4
5 var observer = new MutationObser...
From HTML to JS (2)
1 var els = document.querySelectorAll(
2 '*[data-bind=name]'
3 );
4
5 Array.from(els).forEach(function...
From HTML to JS (2)
1 var els = document.querySelectorAll(
2 '*[data-bind=name]'
3 );
4
5 Array.from(els).forEach(function...
OMG AWESOME WTF
APESHIT INSANE
Things you cannot do
a.k.a. I want it now!
Proxies
Intercepting calls to objects with
JS Object
{ id: 4, city: "Lviv" }
JS Object
{ id: 4, city: "Lviv" }
Application code
JS Object
{ id: 4, city: "Lviv" }
Application code
alert(obj.id)
JS Object
{ id: 4, city: "Lviv" }
Application code
alert(obj.id)
obj.city = "Kiev"
Proxy
JS Object
{ id: 4, city: "Lviv" }
Application code
alert(obj.id)
obj.city = "Kiev"
1 var obj = new Proxy(
2 {
3 id: 4,
4 city: "Lviv"
5 },
6 {
7 get: function(target, name) {
8 console.log('Get for', name)...
1 var obj = new Proxy(
2 {
3 id: 4,
4 city: "Lviv"
5 },
6 {
7 get: function(target, name) {
8 console.log('Get for', name)...
1 var obj = new Proxy(
2 {
3 id: 4,
4 city: "Lviv"
5 },
6 {
7 get: function(target, name) {
8 console.log('Get for', name)...
1 var obj = new Proxy(
2 {
3 id: 4,
4 city: "Lviv"
5 },
6 {
7 get: function(target, name) {
8 console.log('Get for', name)...
1 var obj = new Proxy(
2 {
3 id: 4,
4 city: "Lviv"
5 },
6 {
7 get: function(target, name) {
8 if (name === 'city') {
9 ret...
1 var obj = new Proxy(
2 {
3 id: 4,
4 city: "Lviv"
5 },
6 {
7 get: function(target, name) {
8 if (name === 'city') {
9 ret...
1 var obj = new Proxy(
2 {
3 id: 4,
4 city: "Lviv"
5 },
6 {
7 get: function(target, name) {
8 if (!(name in target)) {
9 t...
1 var obj = new Proxy(
2 {
3 id: 4,
4 city: "Lviv"
5 },
6 {
7 get: function(target, name) {
8 if (!(name in target)) {
9 t...
1 var obj = new Proxy(
2 {
3 id: 4,
4 city: "Lviv"
5 },
6 {
7 set: function(target, name, value) {
8 if (name === 'id'
9 &...
1 var obj = new Proxy(
2 {
3 id: 4,
4 city: "Lviv"
5 },
6 {
7 set: function(target, name, value) {
8 if (name === 'id'
9 &...
1 set: function(target, name, value) {
2 if (target[name] !== value) {
3 console.log('Value for', name, 'changed');
4 }
5 }
Proxies are cool
Aspect Oriented Programming
Logging
Access Control
Generators
Lazy functions
Generators
Lazy functions
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...
Generators are lazy
1 function* turingWinners () {
2 console.log('Hello from our function');
3 yield "Alan J. Perlis";
4 c...
Generators are lazy
1 function* turingWinners () {
2 console.log('Hello from our function');
3 yield "Alan J. Perlis";
4 c...
Generators are lazy
1 function* turingWinners () {
2 console.log('Hello from our function');
3 yield "Alan J. Perlis";
4 c...
Generators are lazy
1 function* turingWinners () {
2 console.log('Hello from our function');
3 yield "Alan J. Perlis";
4 c...
Generators are lazy
1 function* turingWinners () {
2 console.log('Hello from our function');
3 yield "Alan J. Perlis";
4 c...
Call next() to start
1 function* turingWinners () {
2 console.log('Hello from our function');
3 yield "Alan J. Perlis";
4 ...
Call next() to start
1 function* turingWinners () {
2 console.log('Hello from our function');
3 yield "Alan J. Perlis";
4 ...
Call next() to start
1 function* turingWinners () {
2 console.log('Hello from our function');
3 yield "Alan J. Perlis";
4 ...
Call next() to start
1 function* turingWinners () {
2 console.log('Hello from our function');
3 yield "Alan J. Perlis";
4 ...
Call next() to start
1 function* turingWinners () {
2 console.log('Hello from our function');
3 yield "Alan J. Perlis";
4 ...
Call next() to start
1 function* turingWinners () {
2 console.log('Hello from our function');
3 yield "Alan J. Perlis";
4 ...
Call next() to start
1 function* turingWinners () {
2 console.log('Hello from our function');
3 yield "Alan J. Perlis";
4 ...
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...
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...
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...
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...
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...
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)...
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)...
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)...
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)...
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)...
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)...
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)...
Using the generators
1 var nice = generateNumber();
2 nice = filter(nice);
3 nice = map(nice);
4
5 for (var i = 0; i < 3; ...
Using the generators
1 var nice = generateNumber();
2 nice = filter(nice);
3 nice = map(nice);
4
5 for (var i = 0; i < 3; ...
Two way interaction
1 function* printName() {
2 var name = yield 'Whats your name?';
3 console.log('Hello', name);
4 }
5
6...
Two way interaction
1 function* printName() {
2 var name = yield 'Whats your name?';
3 console.log('Hello', name);
4 }
5
6...
Two way interaction
1 function* printName() {
2 var name = yield 'Whats your name?';
3 console.log('Hello', name);
4 }
5
6...
Two way interaction
1 function* printName() {
2 var name = yield 'Whats your name?';
3 console.log('Hello', name);
4 }
5
6...
Two way interaction
1 function* printName() {
2 var name = yield 'Whats your name?';
3 console.log('Hello', name);
4 }
5
6...
Two way interaction
1 function* printName() {
2 var name = yield 'Whats your name?';
3 console.log('Hello', name);
4 }
5
6...
Two way interaction
1 function* printName() {
2 var name = yield 'Whats your name?';
3 console.log('Hello', name);
4 }
5
6...
Two way interaction
1 function* printName() {
2 var name = yield 'Whats your name?';
3 console.log('Hello', name);
4 }
5
6...
Yield and deferred values
• Wrote sync code
• But yield waits until new value comes in...
• So it’s actually async with sy...
1 function* run() {
2 yield sleep(2000);
3 console.log('It has been 2 seconds');
4 }
5
6 function sleep(ms) {
7 return new...
1 function* run() {
2 yield sleep(2000);
3 console.log('It has been 2 seconds');
4 }
5
6 function sleep(ms) {
7 return new...
1 function* run() {
2 yield sleep(2000);
3 console.log('It has been 2 seconds');
4 }
5
6 function sleep(ms) {
7 return new...
1 function* run() {
2 yield sleep(2000);
3 console.log('It has been 2 seconds');
4 }
5
6 function sleep(ms) {
7 return new...
1 function* run() {
2 yield sleep(2000);
3 console.log('It has been 2 seconds');
4 }
5
6 function sleep(ms) {
7 return new...
1 function* run() {
2 yield sleep(2000);
3 console.log('It has been 2 seconds');
4 }
5
6 function sleep(ms) {
7 return new...
1 function* run() {
2 yield sleep(2000);
3 console.log('It has been 2 seconds');
4 }
5
6 function sleep(ms) {
7 return new...
1 function* run() {
2 yield sleep(2000);
3 console.log('It has been 2 seconds');
4 }
5
6 function sleep(ms) {
7 return new...
1 function* run() {
2 yield sleep(2000);
3 console.log('It has been 2 seconds');
4 }
5
6 function sleep(ms) {
7 return new...
http://pag.forbeslindesay.co.uk/#/22
1 run(function* () {
2 var data = yield $.get('/yolo');
3 data = JSON.parse(data);
4 ...
http://pag.forbeslindesay.co.uk/#/22
1 run(function* () {
2 try {
3 var moar = yield $.post('/other');
4 }
5 catch (ex) {
...
http://pag.forbeslindesay.co.uk/#/22
1 run(function* () {
2 var req1 = $.get('http://a');
3 var req2 = $.get('http://b');
...
OMGAWESOME
Thank you!
slideshare.net/janjongboom
slideshare.net/janjongboom
Questions?
ESNext for humans - LvivJS 16 August 2014
ESNext for humans - LvivJS 16 August 2014
ESNext for humans - LvivJS 16 August 2014
ESNext for humans - LvivJS 16 August 2014
ESNext for humans - LvivJS 16 August 2014
ESNext for humans - LvivJS 16 August 2014
ESNext for humans - LvivJS 16 August 2014
ESNext for humans - LvivJS 16 August 2014
ESNext for humans - LvivJS 16 August 2014
ESNext for humans - LvivJS 16 August 2014
ESNext for humans - LvivJS 16 August 2014
ESNext for humans - LvivJS 16 August 2014
Upcoming SlideShare
Loading in …5
×

ESNext for humans - LvivJS 16 August 2014

3,020 views

Published on

Presentation I gave about next version of JavaScript @ LvivJS

Published in: Internet

ESNext for humans - LvivJS 16 August 2014

  1. 1. ES.next for humans @janjongboom LvivJS 2014
  2. 2. @janjongboom
  3. 3. @janjongboom
  4. 4. I hate JavaScript!
  5. 5. VBScript <3 <3 <3
  6. 6. програма Things you could already do Things you needed a framework for Things that were impossible
  7. 7. Things you can already do alt: S*#t that annoys Jan in JavaScript
  8. 8. 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
  9. 9. NodeList is not an array 1 Array.prototype.slice.call( 2 document.querySelectorAll('li') 3 )
  10. 10. NodeList is not an array 1 Array.prototype.slice.call( 2 document.querySelectorAll('li') 3 ) 1 Array.from( 2 document.querySelectorAll('li') 3 )
  11. 11. Variable scoping 1 var a = 7; 2 3 if (something) { 4 var a = 9; 5 doSomethingElse(a); 6 } 7 8 console.log(a);
  12. 12. 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'
  13. 13. 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'
  14. 14. 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'
  15. 15. 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
  16. 16. 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
  17. 17. Tuples Multiple return values
  18. 18. 1 function getPosition() { 2 return [ 12, 91 ]; 3 } 4 5 var pos = getPosition(); 6 var x = pos[0], 7 y = pos[1]; 8 9 function getPosition() { 10 return { x: 12, y: 91 }; 11 } 12 13 var pos = getPosition(); 14 var x = pos.x; 15 y = pos.y;
  19. 19. 1 function getPosition() { 2 return [ 12, 91 ]; 3 } 4 5 var pos = getPosition(); 6 var x = pos[0], 7 y = pos[1]; 8 9 function getPosition() { 10 return { x: 12, y: 91 }; 11 } 12 13 var pos = getPosition(); 14 var x = pos.x; 15 y = pos.y; let [x, y] = getPosition();
  20. 20. 1 function getPosition() { 2 return [ 12, 91 ]; 3 } 4 5 var pos = getPosition(); 6 var x = pos[0], 7 y = pos[1]; 8 9 function getPosition() { 10 return { x: 12, y: 91 }; 11 } 12 13 var pos = getPosition(); 14 var x = pos.x; 15 y = pos.y; let [x, y] = getPosition(); let {x, y} = getPosition();
  21. 21. 1 var data = {}; 2 3 data['jan'] = 'awesome'; 4 data['pete'] = 'not so awesome'; 5 6 var ele1 = document.querySelector('#el1'); 7 data[ele1] = 'first element'; 8 9 var ele2 = document.querySelector('#el2'); 10 data[ele2] = 'second element'; 11 12 console.log(data[ele1]); Maps
  22. 22. 1 var data = {}; 2 3 data['jan'] = 'awesome'; 4 data['pete'] = 'not so awesome'; 5 6 var ele1 = document.querySelector('#el1'); 7 data[ele1] = 'first element'; 8 9 var ele2 = document.querySelector('#el2'); 10 data[ele2] = 'second element'; 11 12 console.log(data[ele1]); Maps
  23. 23. 1 var data = {}; 2 3 data['jan'] = 'awesome'; 4 data['pete'] = 'not so awesome'; 5 6 var ele1 = document.querySelector('#el1'); 7 data[ele1] = 'first element'; 8 9 var ele2 = document.querySelector('#el2'); 10 data[ele2] = 'second element'; 11 12 console.log(data[ele1]); Maps “second element”
  24. 24. 1 var data = {}; 2 3 data['jan'] = 'awesome'; 4 data['pete'] = 'not so awesome'; 5 6 var ele1 = document.querySelector('#el1'); 7 data[ele1] = 'first element'; 8 9 var ele2 = document.querySelector('#el2'); 10 data[ele2] = 'second element'; 11 12 console.log(data[ele1]); Maps
  25. 25. Maps 1 var data = {}; 2 3 data['jan'] = 'awesome'; 4 data['pete'] = 'not so awesome'; 5 6 var ele1 = document.querySelector('#el1'); 7 data[ele1] = 'first element'; 8 9 var ele2 = document.querySelector('#el2'); 10 data[ele2] = 'second element'; 11 12 console.log(data[ele1]);
  26. 26. Maps 1 var data = {}; 2 3 data['jan'] = 'awesome'; 4 data['pete'] = 'not so awesome'; 5 6 var ele1 = document.querySelector('#el1'); 7 data[ele1] = 'first element'; 8 9 var ele2 = document.querySelector('#el2'); 10 data[ele2] = 'second element'; 11 12 console.log(data[ele1]); data[ele2.toString()] ele2.toString() => “[object HTMLDivElement”]
  27. 27. Maps 1 var data = new Map(); 2 3 data.set('jan', 'awesome'); 4 5 data.has('jan'); // true 6 data.get('jan'); // "awesome" 7 8 var ele1 = document.querySelector('#el1'); 9 data.set(ele1, 'first element'); 10 11 var ele2 = document.querySelector('#el2'); 12 data.set(ele2, 'second element'); 13 14 console.log(data.get(ele1)); // "first element"
  28. 28. Maps 1 var data = new Map(); 2 3 data.set('jan', 'awesome'); 4 5 data.has('jan'); // true 6 data.get('jan'); // "awesome" 7 8 var ele1 = document.querySelector('#el1'); 9 data.set(ele1, 'first element'); 10 11 var ele2 = document.querySelector('#el2'); 12 data.set(ele2, 'second element'); 13 14 console.log(data.get(ele1)); // "first element"
  29. 29. Function boilerplate 1 2 someArray 3 .filter(function(item) { 4 return item.isActive; 5 }) 6 .map(function(item) { 7 return item.id; 8 }); 9 10 setTimeout(function() { 11 doSomeMagic() 12 }, 500);
  30. 30. Function boilerplate 1 2 someArray 3 .filter(function(item) { 4 return item.isActive; 5 }) 6 .map(function(item) { 7 return item.id; 8 }); 9 10 setTimeout(function() { 11 doSomeMagic() 12 }, 500); .filter(item => item.isActive)
  31. 31. Function boilerplate 1 2 someArray 3 .filter(function(item) { 4 return item.isActive; 5 }) 6 .map(function(item) { 7 return item.id; 8 }); 9 10 setTimeout(function() { 11 doSomeMagic() 12 }, 500); .filter(item => item.isActive) .map(item => item.id);
  32. 32. Function boilerplate 1 2 someArray 3 .filter(function(item) { 4 return item.isActive; 5 }) 6 .map(function(item) { 7 return item.id; 8 }); 9 10 setTimeout(function() { 11 doSomeMagic() 12 }, 500); .filter(item => item.isActive) .map(item => item.id); setTimeout(() => {
  33. 33. Things you need a framework for a.k.a. Goodbye Angular!
  34. 34. Promises
  35. 35. 1 new Promise(function(resolve, reject) { 2 resolve('Success!'); 3 // or... 4 reject('I failed!'); 5 }); Native promises
  36. 36. Data binding
  37. 37. AngularJS 1 function SomeCtrl() { 2 $scope.name = "Jan"; 3 } 1 <div ng-controller="SomeCtrl"> 2 <input type="text" ng-model="name"> 3 4 Hi {{name}} 5 </div>
  38. 38. Now without a framework
  39. 39. From JS -> HTML 1 <div> 2 <input type="text" data-bind="name"> 3 Hello <span data-bind="name"></span> 4 </div> 1 var scope = { 2 name: 'Jan' 3 }; 4 // ???????
  40. 40. From JS -> HTML 1 <div> 2 <input type="text" data-bind="name"> 3 Hello <span data-bind="name"></span> 4 </div> 1 var scope = { 2 name: 'Jan' 3 }; 4 // ???????
  41. 41. From JS -> HTML 1 <div> 2 <input type="text" data-bind="name"> 3 Hello <span data-bind="name"></span> 4 </div> 1 var scope = { 2 name: 'Jan' 3 }; 4 // ???????
  42. 42. 1 function updateScope() { 2 var els = document.querySelectorAll( 3 '*[data-bind=name]' 4 ); 5 6 Array.from(els).forEach(function(el) { 7 if ('value' in el) // input element 8 el.value = scope.name; 9 else if ('textContent' in el) // normal 10 el.textContent = scope.name; 11 }); 12 } 13 14 updateScope();
  43. 43. 1 function updateScope() { 2 var els = document.querySelectorAll( 3 '*[data-bind=name]' 4 ); 5 6 Array.from(els).forEach(function(el) { 7 if ('value' in el) // input element 8 el.value = scope.name; 9 else if ('textContent' in el) // normal 10 el.textContent = scope.name; 11 }); 12 } 13 14 updateScope();
  44. 44. 1 function updateScope() { 2 var els = document.querySelectorAll( 3 '*[data-bind=name]' 4 ); 5 6 Array.from(els).forEach(function(el) { 7 if ('value' in el) // input element 8 el.value = scope.name; 9 else if ('textContent' in el) // normal 10 el.textContent = scope.name; 11 }); 12 } 13 14 updateScope();
  45. 45. 1 function updateScope() { 2 var els = document.querySelectorAll( 3 '*[data-bind=name]' 4 ); 5 6 Array.from(els).forEach(function(el) { 7 if ('value' in el) // input element 8 el.value = scope.name; 9 else if ('textContent' in el) // normal 10 el.textContent = scope.name; 11 }); 12 } 13 14 updateScope();
  46. 46. 1 function updateScope() { 2 var els = document.querySelectorAll( 3 '*[data-bind=name]' 4 ); 5 6 Array.from(els).forEach(function(el) { 7 if ('value' in el) // input element 8 el.value = scope.name; 9 else if ('textContent' in el) // normal 10 el.textContent = scope.name; 11 }); 12 } 13 14 updateScope(); 1 <div> 2 <input type="text" data-bind="name"> 3 Hello <span data-bind="name"></span> 4 </div>
  47. 47. But what if we change scope.name from JS?
  48. 48. 1 Object.observe(scope, function(changes) { 2 changes.forEach(function(change) { 3 if (change.type === 'update' && 4 change.name === 'name') { 5 updateScope(); 6 } 7 }); 8 }); 9 10 11 setTimeout(function() { 12 scope.name = 'Vladimir'; 13 }, 2000);
  49. 49. 1 Object.observe(scope, function(changes) { 2 changes.forEach(function(change) { 3 if (change.type === 'update' && 4 change.name === 'name') { 5 updateScope(); 6 } 7 }); 8 }); 9 10 11 setTimeout(function() { 12 scope.name = 'Vladimir'; 13 }, 2000);
  50. 50. 1 Object.observe(scope, function(changes) { 2 changes.forEach(function(change) { 3 if (change.type === 'update' && 4 change.name === 'name') { 5 updateScope(); 6 } 7 }); 8 }); 9 10 11 setTimeout(function() { 12 scope.name = 'Vladimir'; 13 }, 2000); { type: "update", name: "name", oldValue: "Jan"}
  51. 51. 1 Object.observe(scope, function(changes) { 2 changes.forEach(function(change) { 3 if (change.type === 'update' && 4 change.name === 'name') { 5 updateScope(); 6 } 7 }); 8 }); 9 10 11 setTimeout(function() { 12 scope.name = 'Vladimir'; 13 }, 2000); { type: "update", name: "name", oldValue: "Jan"}
  52. 52. From HTML -> JS (1) 1 var els = document.querySelectorAll( 2 '*[data-bind=name]' 3 ); 4 5 var observer = new MutationObserver(function() { 6 scope.name = this.textContent; 7 }); 8 9 Array.from(els).forEach(function(el) { 10 observer.observe(el, { childList: true }); 11 });
  53. 53. From HTML -> JS (1) 1 var els = document.querySelectorAll( 2 '*[data-bind=name]' 3 ); 4 5 var observer = new MutationObserver(function() { 6 scope.name = this.textContent; 7 }); 8 9 Array.from(els).forEach(function(el) { 10 observer.observe(el, { childList: true }); 11 });
  54. 54. From HTML to JS (2) 1 var els = document.querySelectorAll( 2 '*[data-bind=name]' 3 ); 4 5 Array.from(els).forEach(function(el) { 6 el.onkeyup = function() { 7 if (el.value) 8 scope.name = el.value; 9 } 10 });
  55. 55. From HTML to JS (2) 1 var els = document.querySelectorAll( 2 '*[data-bind=name]' 3 ); 4 5 Array.from(els).forEach(function(el) { 6 el.onkeyup = function() { 7 if (el.value) 8 scope.name = el.value; 9 } 10 });
  56. 56. OMG AWESOME WTF APESHIT INSANE
  57. 57. Things you cannot do a.k.a. I want it now!
  58. 58. Proxies Intercepting calls to objects with
  59. 59. JS Object { id: 4, city: "Lviv" }
  60. 60. JS Object { id: 4, city: "Lviv" } Application code
  61. 61. JS Object { id: 4, city: "Lviv" } Application code alert(obj.id)
  62. 62. JS Object { id: 4, city: "Lviv" } Application code alert(obj.id) obj.city = "Kiev"
  63. 63. Proxy JS Object { id: 4, city: "Lviv" } Application code alert(obj.id) obj.city = "Kiev"
  64. 64. 1 var obj = new Proxy( 2 { 3 id: 4, 4 city: "Lviv" 5 }, 6 { 7 get: function(target, name) { 8 console.log('Get for', name); 9 return target[name]; 10 } 11 } 12 ); 13 14 alert(obj.city); 15 // Get for 'city'
  65. 65. 1 var obj = new Proxy( 2 { 3 id: 4, 4 city: "Lviv" 5 }, 6 { 7 get: function(target, name) { 8 console.log('Get for', name); 9 return target[name]; 10 } 11 } 12 ); 13 14 alert(obj.city); 15 // Get for 'city'
  66. 66. 1 var obj = new Proxy( 2 { 3 id: 4, 4 city: "Lviv" 5 }, 6 { 7 get: function(target, name) { 8 console.log('Get for', name); 9 return target[name]; 10 } 11 } 12 ); 13 14 alert(obj.city); 15 // Get for 'city'
  67. 67. 1 var obj = new Proxy( 2 { 3 id: 4, 4 city: "Lviv" 5 }, 6 { 7 get: function(target, name) { 8 console.log('Get for', name); 9 return target[name]; 10 } 11 } 12 ); 13 14 alert(obj.city); 15 // Get for 'city'
  68. 68. 1 var obj = new Proxy( 2 { 3 id: 4, 4 city: "Lviv" 5 }, 6 { 7 get: function(target, name) { 8 if (name === 'city') { 9 return 'Kiev'; 10 } 11 return target[name]; 12 } 13 } 14 ); 15 16 console.log(obj.city); 17 // returns 'Kiev' ?!!
  69. 69. 1 var obj = new Proxy( 2 { 3 id: 4, 4 city: "Lviv" 5 }, 6 { 7 get: function(target, name) { 8 if (name === 'city') { 9 return 'Kiev'; 10 } 11 return target[name]; 12 } 13 } 14 ); 15 16 console.log(obj.city); 17 // returns 'Kiev' ?!!
  70. 70. 1 var obj = new Proxy( 2 { 3 id: 4, 4 city: "Lviv" 5 }, 6 { 7 get: function(target, name) { 8 if (!(name in target)) { 9 throw 'has no property "' + name + '"' 10 } 11 return target[name]; 12 } 13 } 14 ); 15 16 console.log(obj.citi); ERROR: has no property 'citi'
  71. 71. 1 var obj = new Proxy( 2 { 3 id: 4, 4 city: "Lviv" 5 }, 6 { 7 get: function(target, name) { 8 if (!(name in target)) { 9 throw 'has no property "' + name + '"' 10 } 11 return target[name]; 12 } 13 } 14 ); 15 16 console.log(obj.citi); ERROR: has no property 'citi'
  72. 72. 1 var obj = new Proxy( 2 { 3 id: 4, 4 city: "Lviv" 5 }, 6 { 7 set: function(target, name, value) { 8 if (name === 'id' 9 && typeof value !== 'number') 10 throw 'id must be numeric'; 11 target[name] = value; 12 } 13 } 14 ); 15 16 obj.id = '5'; ERROR: id must be numeric
  73. 73. 1 var obj = new Proxy( 2 { 3 id: 4, 4 city: "Lviv" 5 }, 6 { 7 set: function(target, name, value) { 8 if (name === 'id' 9 && typeof value !== 'number') 10 throw 'id must be numeric'; 11 target[name] = value; 12 } 13 } 14 ); 15 16 obj.id = '5'; ERROR: id must be numeric
  74. 74. 1 set: function(target, name, value) { 2 if (target[name] !== value) { 3 console.log('Value for', name, 'changed'); 4 } 5 }
  75. 75. Proxies are cool Aspect Oriented Programming Logging Access Control
  76. 76. Generators Lazy functions
  77. 77. Generators Lazy functions
  78. 78. 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 }
  79. 79. 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();
  80. 80. 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();
  81. 81. 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();
  82. 82. 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();
  83. 83. 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 $
  84. 84. 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());
  85. 85. 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());
  86. 86. 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());
  87. 87. 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 }
  88. 88. 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());
  89. 89. 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());
  90. 90. 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 }
  91. 91. 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);
  92. 92. 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);
  93. 93. 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);
  94. 94. 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);
  95. 95. 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);
  96. 96. 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 }
  97. 97. 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 }
  98. 98. 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
  99. 99. 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
  100. 100. 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
  101. 101. 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
  102. 102. 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
  103. 103. 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 }
  104. 104. 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 }
  105. 105. 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);
  106. 106. 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);
  107. 107. 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);
  108. 108. 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);
  109. 109. 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);
  110. 110. 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);
  111. 111. 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?
  112. 112. 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 }
  113. 113. 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 }
  114. 114. 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 });
  115. 115. 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 });
  116. 116. 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 });
  117. 117. 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 });
  118. 118. 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 });
  119. 119. 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 });
  120. 120. 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 });
  121. 121. 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 });
  122. 122. 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 });
  123. 123. http://pag.forbeslindesay.co.uk/#/22 1 run(function* () { 2 var data = yield $.get('/yolo'); 3 data = JSON.parse(data); 4 });
  124. 124. http://pag.forbeslindesay.co.uk/#/22 1 run(function* () { 2 try { 3 var moar = yield $.post('/other'); 4 } 5 catch (ex) { 6 console.error('Oh noes!', ex); 7 } 8 });
  125. 125. http://pag.forbeslindesay.co.uk/#/22 1 run(function* () { 2 var req1 = $.get('http://a'); 3 var req2 = $.get('http://b'); 4 5 $('.status').text( yield req1 + yield req2); 6 });
  126. 126. OMGAWESOME
  127. 127. Thank you! slideshare.net/janjongboom
  128. 128. slideshare.net/janjongboom Questions?

×