
ES7 The Evolution of JavaScript Who is Jafar Husain? • Architect of Falcor, Netflix’s OSS data platform • Netflix representative TC-39 • Formerly worked for MS and GE ES6 spec will be finalized in June 2015 Isn’t it too early to talk about ES7? No. ES7 features are already starting to roll into browsers. ES5 ES6 ES7 ES7ES6 2 BIG ES7 #1 Easier Model/View Synchronization Model View #2 Easier Async Programming pull push Arrow Functions => ES6 Arrow Functions function(x) { return x + 1; } x => x + 1 function(x, y) { return x + y; } (x, y) => x + y ES 5 6 Controller View Model Why not natively support change notification? ? Object.observe ES7 Object.observe var person = {}; var changesHandler = changes => console.log(changes); Object.observe(person, changesHandler); Object.observe person = { name: , “Dana T. Miller” “Dana Miller” }; employer: “Tommy's Box Store” [ { "type":”updatetype":”newtype":”reconfiguretype":”delete", ", ", "name":”namename":”employer”, ” ” ”, “ } oldValue: “Dana Miller” : “Tommy's Box Store” } ] ] Object.unobserve Object.unobserve(person, changesHandler); unobserve The word you’ve entered isn’t in the diconary. irregardless regardless. The Event Loop Queue Observe notification person.name = “Jim”; person.age = 22; Browser Timeout Event Handler XHR handler render handler Current Task Tasks on the event loop How to avoid the Notification Storm? Microtasks ES6 Event Loop Queue + Microtasks Observe handler person.name = “Jim”; person.age = 23; Browser Timeout Event handler XHR handler render handler Current Task Tasks on the event loop Object.observe on Microtasks sync sync Model A Model B DOM Try Object.observe Object.observe 0. Strawman ES Feature 1. Proposal 2. Draft Maturity Stages 3. Candidate 4. Finished Maturity Stage 2: Draft “Commi&ee expects the feature to be developed and…included in the standard.” How can we make async programming easier? ? Blocking is Easy function getStockPrice(name) { var symbol = getStockSymbol(name); var price = getStockPrice(symbol); return price; } Blocking means Pulling Data delivered in return position price = getStockPrice(“Devine Inc.”); pull What if we want to wait instead of block? ? Waiting means Pushing Data delivered in argument position getStockPrice(“Devine Inc.”, price => { … }); push The Pyramid of DOOM Blocking/Pulling function getStockPrice(name) { var symbol = getStockSymbol(name); var price = getStockPrice(symbol); return price; } Waiting/Pushing function getStockPrice(name, cb) { getStockSymbol(name, ((name, (error, symbol) => { error, symbol) => { if (error) { if (error) { cb(error); } else { getStockPrice(symbol, ((symbol, (error, price) => { error, price) => { if (error) { if (error) { cb(error); } else { cb(price); } }) } }) } Pulling and Pushing are symmetrical Why must waiting be so much harder than blocking? ? Promises ES6 Promises 42 X promise.then(value => {…}, error => {…}); function getStockPrice(name) { var symbol = getStockSymbol(name); sync var price = getStockPrice(symbol); return price; } function getStockPrice(name) { async return getStockSymbol(name). then(symbol => getStockPrice(symbol)); } Not bad, but… …why does waiting have to look so different than blocking? ? function getStockPrice(name) { var symbol = getStockSymbol(name); var price = getStockPrice(symbol); sync return price; } function getStockPrice(name) { function* getStockPrice(name) { return var symbol = getStockSymbolyield getStockSymbol(name). (name); async var price = then(symbol => yield getStockPricegetStockPrice(symbol); (symbol)); return price; } } Generator function ES6 A generator function can return multiple values. done 96 23 Generator Functions in ES6 function* getNumbers() { yield 42; yield 32; return 19; } Retrieving function* results function* getNumbers() { yield 42; yield 32; return 19; } > var iterator = getNumbers(); > console.log(iterator.next()); > { value: 42, done: false } > console.log(iterator.next()); > { value: 32, done: false } > console.log(iterator.next()); > { value: 19, done: true } > Iteration Consumer Producer 42 var iterator = var result = producer.iterator.iteratornext() (); Iteration Consumer Producer 39 var result = iterator.next() Iteration Consumer Producer done var result = iterator.next() How Yield Works function* function getFibonnacciSequencegetFibonnacciSequence() { () { function getFibonnacciSequence() { return { return { next: function() { next: function() { let val1 = 0, val2 = 1, swap; let val1 = 0, val2 = 1, swap, let val1 = 0, val2 = 1, swap, state = 0; state = 0; let val1 = 0, val2 = 1, swap, state = 0; switch(state) { switch(state) { switch(state) { case 0: case 0: state = 1; state = 1; yield return {value: val1, done: false}; val1; return {value: val1, done: false}; return {value: val1, done: false}; case 1: case 1: state = 2; state = 2; yield return {value: val2, done: false}; val2; return {value: val2, done: false}; while(true) { default: default: swap = val1 + val2; swap = val1 + val2; swap = val1 + val2; val2 = swap; val2 = swap; val2 = swap; val1 = val2; val1 = val2; val1 = val2; return {value: swap, done: false}; yield swap; return {value: swap, done: false}; } } } } } } } } } } All ES6 collections are Iterable. ES6 Iterator Pattern > var iterator = [42, 39][@@iterator](); > console.log(iterator.next()); > { value: 42, done: false } > console.log(iterator.next()); > { value: 39, done: false } > console.log(iterator.next()); > { done: true } > Consuming Iterables with for..of > for(var x of [42,39,17]) { console.log(x); } > 42 > 39 > 17 > If generator functions return iterators… …why aren’t they called Iterator functions? ? Iterator Generator Observer A Generator is an Iterator yield value generator.next().value; throw an error try { generator.next(); } catch(err) { ... } var pair = generator.next(); return value if (pair.done) alert(pair.value); pull A Generator is an Observer receive data generator.next(5); receive an error generator.throw(“fail”); receive return value generator.return(5); push Iteration only allows data to flow one-way. done 96 23 Generators allow feedback. done 21 99 96 33 Waiting with Async Iteration function* getStockPrice(name) { var symbol = yield getStockSymbol(name); var price = yield getStockPrice(symbol); return price; } > spawn(getStockprice(“Pfizer”)). then( price => console.log(price), error => console.error(error)); > 353.22 Async Iteration Consumer Producer “PFE” result.thenvar generator = var result = (data => …, error => …)getStockPricegenerator.next(‘Pfizer’);() var symbol = yield getStockSymbol(‘Pfizer’); Async Iteration Consumer Producer 27.83“PFE” result.thenvar result = (data => …, error => …)generator.next(“PFE”) var symbol = price = yield yield“PFE” getStockPricegetStockSymbol(symbol);(‘Pfizer’); Async Iteration Consumer Producer 27.83 done var result = generator.next(“27.83”) varreturn price price = price = 27.83yield getStockPrice(symbol); Asynchronous Iteration function* getStockPrice(name) { var symbol = yield symbol = “JNJ”; getStockSymbolsymbolPromise; (name); producer var price = yield price = 420.25; getStockPricepricePromise; (symbol) return price; return price; } function spawn(generator) { return new Promise((accept, reject) => { return new Promise((accept, reject) => { var onResult = = lastPromiseResult420.25 “JNJ” => { consumer var {value, done} = {{value:generator.next{valuevalue:: symbolPromise420.25pricePromise,( done: true}lastPromiseResult420.25 , done: false}; , done: false}; “JNJ” ; ); if (!done) { value.thenvalue.then(onResult, reject); } else accept(value); }; onResult(); }); }); } > spawn( thengetStockPrice(“Johnson and Johnson”)).then((console.log); );§ > 420.25 Waiting with with Task.js function* getStockPrice(name) { var symbol = yield getStockSymbol(name); var price = yield getStockPrice(symbol); return price; } var result = spawn(getStockPrice.bind(null, “Pfizer”)); result.then(console.log, console.error); Get Task.js Why should easy waiting require a library? ? Async Functions ES7 Async Functions in ES7 functionasync function * getStockPricegetStockPrice(name) { (name) { var symbol = yield symbol = await getStockSymbol(name); var price = yield await getStockPrice(symbol); return price; } var result = spawn (getStockPrice.bindgetStockPrice (“PFE”) ; (null, “PFE”)); result.then(console.log, console.error); function getStockPrice(name) { var symbol = getStockSymbol(name); var price = getStockPrice(symbol); sync return price; } async function getStockPrice(name) { var symbol = await getStockSymbol(name); async var price = await getStockPrice(symbol); return price; } Symmetrical support for push and pull functions. ES7 Async Functions Try Async Functions The await keyword makes it easy to wait on an async value… …but what if you need to wait on an async stream of values? ? Waiting on a stream with for…on async function getNextPriceSpike(stock, threshold) { var delta, oldPrice, price; for(var price on new WebSocket(“/prices/" + stock)) { if (oldPrice == null) { oldPrice = price; } else { delta = Math.abs(price - oldPrice); oldPrice = price; if (delta > threshold) { return { price: price, oldPrice: oldPrice }; } } } } > getNextPriceSpike(“JNJ”,2.50).then(diff => console.log(diff)); > { price: 420.22, oldPrice: 423.19 } Unfortunately there’s a problem. The web has no standard Observable interface. ObservationIteration Consumer ProducerConsumer Observation Producer Consumer b done 42 39 observer.nextreturn(39)(42)() producer.observer(observer); The Web’s Many Observable APIs • DOM Events • Websockets • Server-sent Events • Node Streams • Service Workers
Details
-
File Typepdf
-
Upload Time-
-
Content LanguagesEnglish
-
Upload UserAnonymous/Not logged-in
-
File Pages125 Page
-
File Size-