Top Banner
ES.next for humans @janjongboom LvivJS 2014
140

ESNext for humans - LvivJS 16 August 2014

Jan 15, 2015

Download

Internet

Jan Jongboom

Presentation I gave about next version of JavaScript @ LvivJS
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: ESNext for humans - LvivJS 16 August 2014

ES.next for humans

@janjongboomLvivJS 2014

Page 2: ESNext for humans - LvivJS 16 August 2014

@janjongboom

Page 3: ESNext for humans - LvivJS 16 August 2014

@janjongboom

Page 4: ESNext for humans - LvivJS 16 August 2014
Page 5: ESNext for humans - LvivJS 16 August 2014

I hate JavaScript!

Page 6: ESNext for humans - LvivJS 16 August 2014
Page 7: ESNext for humans - LvivJS 16 August 2014

VBScript<3 <3 <3

Page 8: ESNext for humans - LvivJS 16 August 2014
Page 9: ESNext for humans - LvivJS 16 August 2014
Page 10: ESNext for humans - LvivJS 16 August 2014

програмаThings you could already do

Things you needed a framework for

Things that were impossible

Page 11: ESNext for humans - LvivJS 16 August 2014

Things you can already doalt: S*#t that annoys Jan in JavaScript

Page 12: ESNext for humans - LvivJS 16 August 2014

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

Page 13: ESNext for humans - LvivJS 16 August 2014

NodeList is not an array

1 Array.prototype.slice.call( 2 document.querySelectorAll('li') 3 )

Page 14: ESNext for humans - LvivJS 16 August 2014

NodeList is not an array

1 Array.prototype.slice.call( 2 document.querySelectorAll('li') 3 )

1 Array.from( 2 document.querySelectorAll('li') 3 )

Page 15: ESNext for humans - LvivJS 16 August 2014

Variable scoping

1 var a = 7; 2 3 if (something) { 4 var a = 9; 5 doSomethingElse(a); 6 } 7 8 console.log(a);

Page 16: ESNext for humans - LvivJS 16 August 2014

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'

Page 17: ESNext for humans - LvivJS 16 August 2014

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'

Page 18: ESNext for humans - LvivJS 16 August 2014

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'

Page 19: ESNext for humans - LvivJS 16 August 2014

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

Page 20: ESNext for humans - LvivJS 16 August 2014

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

Page 21: ESNext for humans - LvivJS 16 August 2014

TuplesMultiple return values

Page 22: ESNext for humans - LvivJS 16 August 2014

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;

Page 23: ESNext for humans - LvivJS 16 August 2014

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();

Page 24: ESNext for humans - LvivJS 16 August 2014

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();

Page 25: ESNext for humans - LvivJS 16 August 2014

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

Page 26: ESNext for humans - LvivJS 16 August 2014

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

Page 27: ESNext for humans - LvivJS 16 August 2014

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”

Page 28: ESNext for humans - LvivJS 16 August 2014

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

Page 29: ESNext for humans - LvivJS 16 August 2014

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]);

Page 30: ESNext for humans - LvivJS 16 August 2014

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”]

Page 31: ESNext for humans - LvivJS 16 August 2014

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"

Page 32: ESNext for humans - LvivJS 16 August 2014

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"

Page 33: ESNext for humans - LvivJS 16 August 2014

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);

Page 34: ESNext for humans - LvivJS 16 August 2014

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)

Page 35: ESNext for humans - LvivJS 16 August 2014

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);

Page 36: ESNext for humans - LvivJS 16 August 2014

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(() => {

Page 37: ESNext for humans - LvivJS 16 August 2014
Page 38: ESNext for humans - LvivJS 16 August 2014

Things you need a framework fora.k.a. Goodbye Angular!

Page 39: ESNext for humans - LvivJS 16 August 2014

Promises

Page 40: ESNext for humans - LvivJS 16 August 2014

1 new Promise(function(resolve, reject) { 2 resolve('Success!'); 3 // or... 4 reject('I failed!'); 5 });

Native promises

Page 41: ESNext for humans - LvivJS 16 August 2014

Data binding

Page 42: ESNext for humans - LvivJS 16 August 2014

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>

Page 43: ESNext for humans - LvivJS 16 August 2014

Now without a framework

Page 44: ESNext for humans - LvivJS 16 August 2014

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 // ???????

Page 45: ESNext for humans - LvivJS 16 August 2014

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 // ???????

Page 46: ESNext for humans - LvivJS 16 August 2014

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 // ???????

Page 47: ESNext for humans - LvivJS 16 August 2014

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();

Page 48: ESNext for humans - LvivJS 16 August 2014

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();

Page 49: ESNext for humans - LvivJS 16 August 2014

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();

Page 50: ESNext for humans - LvivJS 16 August 2014

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();

Page 51: ESNext for humans - LvivJS 16 August 2014

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>

Page 52: ESNext for humans - LvivJS 16 August 2014

But what if we change scope.name from JS?

Page 53: ESNext for humans - LvivJS 16 August 2014

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);

Page 54: ESNext for humans - LvivJS 16 August 2014

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);

Page 55: ESNext for humans - LvivJS 16 August 2014

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"}

Page 56: ESNext for humans - LvivJS 16 August 2014

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"}

Page 57: ESNext for humans - LvivJS 16 August 2014
Page 58: ESNext for humans - LvivJS 16 August 2014

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 });

Page 59: ESNext for humans - LvivJS 16 August 2014

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 });

Page 60: ESNext for humans - LvivJS 16 August 2014
Page 61: ESNext for humans - LvivJS 16 August 2014

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 });

Page 62: ESNext for humans - LvivJS 16 August 2014

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 });

Page 63: ESNext for humans - LvivJS 16 August 2014
Page 64: ESNext for humans - LvivJS 16 August 2014

OMG AWESOME WTFAPESHIT INSANE

Page 65: ESNext for humans - LvivJS 16 August 2014

Things you cannot doa.k.a. I want it now!

Page 66: ESNext for humans - LvivJS 16 August 2014

ProxiesIntercepting calls to objects with

Page 67: ESNext for humans - LvivJS 16 August 2014

JS Object{ id: 4, city: "Lviv" }

Page 68: ESNext for humans - LvivJS 16 August 2014

JS Object{ id: 4, city: "Lviv" }

Application code

Page 69: ESNext for humans - LvivJS 16 August 2014

JS Object{ id: 4, city: "Lviv" }

Application code

alert(obj.id)

Page 70: ESNext for humans - LvivJS 16 August 2014

JS Object{ id: 4, city: "Lviv" }

Application code

alert(obj.id) obj.city = "Kiev"

Page 71: ESNext for humans - LvivJS 16 August 2014

Proxy

JS Object{ id: 4, city: "Lviv" }

Application code

alert(obj.id) obj.city = "Kiev"

Page 72: ESNext for humans - LvivJS 16 August 2014

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'

Page 73: ESNext for humans - LvivJS 16 August 2014

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'

Page 74: ESNext for humans - LvivJS 16 August 2014

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'

Page 75: ESNext for humans - LvivJS 16 August 2014

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'

Page 76: ESNext for humans - LvivJS 16 August 2014

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' ?!!

Page 77: ESNext for humans - LvivJS 16 August 2014

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' ?!!

Page 78: ESNext for humans - LvivJS 16 August 2014

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'

Page 79: ESNext for humans - LvivJS 16 August 2014

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'

Page 80: ESNext for humans - LvivJS 16 August 2014

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

Page 81: ESNext for humans - LvivJS 16 August 2014

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

Page 82: ESNext for humans - LvivJS 16 August 2014

1 set: function(target, name, value) { 2 if (target[name] !== value) { 3 console.log('Value for', name, 'changed'); 4 } 5 }

Page 83: ESNext for humans - LvivJS 16 August 2014

Proxies are coolAspect Oriented ProgrammingLoggingAccess Control

Page 84: ESNext for humans - LvivJS 16 August 2014
Page 85: ESNext for humans - LvivJS 16 August 2014

GeneratorsLazy functions

Page 86: ESNext for humans - LvivJS 16 August 2014

GeneratorsLazy functions

Page 87: ESNext for humans - LvivJS 16 August 2014

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 }

Page 88: ESNext for humans - LvivJS 16 August 2014

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();

Page 89: ESNext for humans - LvivJS 16 August 2014

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();

Page 90: ESNext for humans - LvivJS 16 August 2014

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();

Page 91: ESNext for humans - LvivJS 16 August 2014

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();

Page 92: ESNext for humans - LvivJS 16 August 2014

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 $

Page 93: ESNext for humans - LvivJS 16 August 2014

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());

Page 94: ESNext for humans - LvivJS 16 August 2014

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());

Page 95: ESNext for humans - LvivJS 16 August 2014

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());

Page 96: ESNext for humans - LvivJS 16 August 2014

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.jsHello from our function{ value: 'Alan J. Perlis', done: false }

Page 97: ESNext for humans - LvivJS 16 August 2014

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());

Page 98: ESNext for humans - LvivJS 16 August 2014

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());

Page 99: ESNext for humans - LvivJS 16 August 2014

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.jsHello from our function{ value: 'Alan J. Perlis', done: false }I returned the first one{ value: 'Maurice Wilkes', done: false }

Page 100: ESNext for humans - LvivJS 16 August 2014

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);

Page 101: ESNext for humans - LvivJS 16 August 2014

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);

Page 102: ESNext for humans - LvivJS 16 August 2014

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);

Page 103: ESNext for humans - LvivJS 16 August 2014

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);

Page 104: ESNext for humans - LvivJS 16 August 2014

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);

Page 105: ESNext for humans - LvivJS 16 August 2014

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 }

Page 106: ESNext for humans - LvivJS 16 August 2014

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 }

Page 107: ESNext for humans - LvivJS 16 August 2014

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

Page 108: ESNext for humans - LvivJS 16 August 2014

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

Page 109: ESNext for humans - LvivJS 16 August 2014

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 == 02,4,6

Page 110: ESNext for humans - LvivJS 16 August 2014

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 == 02,4,6

Page 111: ESNext for humans - LvivJS 16 August 2014

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 == 02,4,6

n * n4,16,36

Page 112: ESNext for humans - LvivJS 16 August 2014

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 }

Page 113: ESNext for humans - LvivJS 16 August 2014

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 }

Page 114: ESNext for humans - LvivJS 16 August 2014
Page 115: ESNext for humans - LvivJS 16 August 2014

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);

Page 116: ESNext for humans - LvivJS 16 August 2014

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);

Page 117: ESNext for humans - LvivJS 16 August 2014

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);

Page 118: ESNext for humans - LvivJS 16 August 2014

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);

Page 119: ESNext for humans - LvivJS 16 August 2014

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);

Page 120: ESNext for humans - LvivJS 16 August 2014

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);

Page 121: ESNext for humans - LvivJS 16 August 2014

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.jsIt: Whats your name?

Page 122: ESNext for humans - LvivJS 16 August 2014

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.jsIt: Whats your name?$ node --harmony test.jsIt: Whats your name?Hello Jan Jongboom{ value: undefined, done: true }

Page 123: ESNext for humans - LvivJS 16 August 2014

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 }

Page 124: ESNext for humans - LvivJS 16 August 2014

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 });

Page 125: ESNext for humans - LvivJS 16 August 2014

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 });

Page 126: ESNext for humans - LvivJS 16 August 2014

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 });

Page 127: ESNext for humans - LvivJS 16 August 2014

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 });

Page 128: ESNext for humans - LvivJS 16 August 2014

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 });

Page 129: ESNext for humans - LvivJS 16 August 2014

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 });

Page 130: ESNext for humans - LvivJS 16 August 2014

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 });

Page 131: ESNext for humans - LvivJS 16 August 2014

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 });

Page 132: ESNext for humans - LvivJS 16 August 2014

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 });

Page 133: ESNext for humans - LvivJS 16 August 2014

http://pag.forbeslindesay.co.uk/#/22

1 run(function* () { 2 var data = yield $.get('/yolo'); 3 data = JSON.parse(data); 4 });

Page 134: ESNext for humans - LvivJS 16 August 2014

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 });

Page 135: ESNext for humans - LvivJS 16 August 2014

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 });

Page 136: ESNext for humans - LvivJS 16 August 2014

OMGAWESOME

Page 137: ESNext for humans - LvivJS 16 August 2014
Page 138: ESNext for humans - LvivJS 16 August 2014
Page 139: ESNext for humans - LvivJS 16 August 2014

Thank you!

slideshare.net/janjongboom

Page 140: ESNext for humans - LvivJS 16 August 2014

slideshare.net/janjongboom

Questions?