Slide 1

Slide 1 text

Abusing ES6+ features for nicer parallelism * Disclaimer: no people, animals or JS features were harmed during the talk Ingvar Stepanyan aka @RReverser

Slide 2

Slide 2 text

Calculation in the main thread // get inputs var x = document.getElementById("x").value; var y = document.getElementById("y").value; // VERY useful calculations for (var end = Date.now() + 3000; Date.now() < end; ); var result = x * y; // output result document.getElementById("output").value = result; jsbin

Slide 3

Slide 3 text

Parallelism looks cool

Slide 4

Slide 4 text

…but implementations might hurt

Slide 5

Slide 5 text

Web Workers: client (main thread) var worker = new Worker("worker.js"); worker.addEventListener("message", function (event) { // output result document.getElementById("output").value = event.data.result; }); // get inputs var x = document.getElementById("x").value; var y = document.getElementById("y").value; worker.postMessage({ x: x, y: y });

Slide 6

Slide 6 text

Web Workers: server (worker) self.addEventListener("message", function (event) { // get inputs var x = event.data.x; var y = event.data.y; // VERY useful calculations for (var end = Date.now() + 3000; Date.now() < end; ); var result = x * y; postMessage({ result: result }); });

Slide 7

Slide 7 text

Web Workers: client (main thread) var worker = new Worker("worker.js"), inc = 0; // get inputs var id = inc++; var x = document.getElementById("x").value; var y = document.getElementById("y").value; worker.addEventListener("message", function handler(event) { if (event.data.id === id) { this.removeEventListener("message", handler); // output result document.getElementById("output").value = event.data.result; } }); worker.postMessage({ id: id, x: x, y: y });

Slide 8

Slide 8 text

Web Workers: server (worker) self.addEventListener("message", function (event) { // get inputs var id = event.data.id; var x = event.data.x; var y = event.data.y; // VERY useful calculations for (var end = Date.now() + 3000; Date.now() < end; ); var result = x * y; postMessage({ id: id, result: result }); }); jsbin

Slide 9

Slide 9 text

Calculation in the main thread // get inputs var x = document.getElementById("x").value; var y = document.getElementById("y").value; // VERY useful calculations for (var end = Date.now() + 3000; Date.now() < end; ); var result = x * y; // output result document.getElementById("output").value = result;

Slide 10

Slide 10 text

Web Workers //// index.js ////
 var worker = new Worker("worker.js"), inc = 0; // get inputs var id = inc++; var x = document.getElementById("x").value; var y = document.getElementById("y").value; worker.addEventListener("message", function handler(event) { if (event.data.id === id) { this.removeEventListener("message", handler); // output result document.getElementById("output").value = event.data.result; } }); worker.postMessage({ id: id, x: x, y: y }); //// worker.js ////
 self.addEventListener("message", function (event) { // get inputs var id = event.data.id; var x = event.data.x; var y = event.data.y; // VERY useful calculations for (var end = Date.now() + 3000; Date.now() < end;); var result = x * y; postMessage({ id: id, result: result }); });

Slide 11

Slide 11 text

No content

Slide 12

Slide 12 text

Calculation in the main thread // get inputs var x = document.getElementById("x").value; var y = document.getElementById("y").value; // VERY useful calculations for (var end = Date.now() + 3000; Date.now() < end; ); var result = x * y; // output result document.getElementById("output").value = result;

Slide 13

Slide 13 text

Dream API parallel(function () { // get inputs var x = document.getElementById("x").value; var y = document.getElementById("y").value; // VERY useful calculations for (var end = Date.now() + 3000; Date.now() < end;); var result = x * y; // output result document.getElementById("output").value = result; });

Slide 14

Slide 14 text

Let’s mix some stuff

Slide 15

Slide 15 text

ES6: Promise API doSomethingAsync().then( function onSuccess(result) {}, function onError(error) {} ) // or just: return doSomethingAsync().then(function (result) { // do something with result })

Slide 16

Slide 16 text

ES6: Promise API $.ajax(url).then(function (data) { $('#result').html(data); var status = $('#status').html('Download complete.'); return status.fadeIn().promise().then(function () { return sleep(2000); }).then(function () { return status.fadeOut(); }); });

Slide 17

Slide 17 text

ES6: Promise API $.ajax(url).then(data => { $('#result').html(data); var status = $('#status').html('Download complete.'); return ( status.fadeIn().promise() .then(() => sleep(2000)) .then(() => status.fadeOut()) ); });

Slide 18

Slide 18 text

ES8: async/await var data = await $.ajax(url); $('#result').html(data); var status = $('#status').html('Download complete.'); await status.fadeIn.promise(); await sleep(2000); await status.fadeOut();

Slide 19

Slide 19 text

ES8: async/await var expr = await promise;
 nextStatement(); var expr; promise.then(result => { expr = result; nextStatement(); });

Slide 20

Slide 20 text

ES8: async/await console.log('Hello'); await { then: resolve => setTimeout(resolve, 3000) }; console.log('world');

Slide 21

Slide 21 text

ES6: Proxy API var proxy = new Proxy({}, { get(target, name) { return name; }, set(target, name, value) { console.log(name, '=', value); }, // ... }); proxy.a; // 'a' proxy[0]; // '0' proxy.a = 1; // console: 'a = 1' proxy.b = 2; // console: 'b = 2'

Slide 22

Slide 22 text

ES6: Proxy API var proxy = new Proxy({}, { get(target, name) { if (name === 'then') { return resolve => resolve(target.name); } return new Proxy({ name }, this); } }); proxy.a.then(console.log); // 'a' proxy.a.b.c.then(console.log); // 'c' proxy[0].then(console.log); // '0'

Slide 23

Slide 23 text

Let’s mix! var proxy = new Proxy({}, { get(target, name) { if (name === 'then') { return resolve => resolve(target.name); } return new Proxy({ name }, this); } }); console.log(await proxy.a); // ‘a' console.log(await proxy.a.b.c); // 'c' console.log(await proxy[0]); // '0'

Slide 24

Slide 24 text

Let’s mix! var proxy = new Proxy({}, { get(target, name) { var chain = { type: 'get', target, name }; if (name === 'then') { return askMainThread(chain); } return new Proxy(chain, this); } }); proxy.a; // {type: 'get', target: {}, name: 'a'} proxy.a.b; // {type: 'get', target: {…, name: 'a'}, name: 'b'} await proxy.a.b.c; // 'a.b.c'

Slide 25

Slide 25 text

ES6: Proxy API await proxy.document.getElementById('x').value // into: askMainThread({ type: 'get', target: { type: 'call', target: { type: 'get', target: { type: 'get', target: {}, name: 'document' }, name: 'getElementById' }, args: ['x'] }, name: 'value' })(resolve => …, reject => …)

Slide 26

Slide 26 text

ES8-powered API parallel(async function (proxy) { // get inputs var x = await proxy.document.getElementById("x").value; var y = await proxy.document.getElementById("y").value; // VERY useful calculations for (var end = Date.now() + 3000; Date.now() < end;); var result = x * y; // output result proxy.document.getElementById("output").value = result; });

Slide 27

Slide 27 text

ES8-powered API (just like we wanted!) parallel(async function ({ document }) { // get inputs var x = await document.getElementById("x").value; var y = await document.getElementById("y").value; // VERY useful calculations for (var end = Date.now() + 3000; Date.now() < end;); var result = x * y; // output result document.getElementById("output").value = result; });

Slide 28

Slide 28 text

Thanks!