SlideShare a Scribd company logo
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
var result = load();
function load() {
var data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
return data;
};
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
function foo() {
setTimeout(function fn() {
result.concat([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
}, 3000);
}
foo()
fn()
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
var start = new Date();
setTimeout(function () {
var end = new Date();
console.log('Timeelapsed:', end - start, 'ms');
}, 500);
while (new Date() - start < 1000) { };
What will be the result:
1. 500 < result < 1000
2. 1000 < result < 1500
3. 1500 < result
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
This API does not guarantee that timers will run exactly on schedule.
Delays due to CPU load, other tasks, etc, are to be expected.
console.log("a");
setTimeout(function () { console.log("c"); }, 500);
setTimeout(function () { console.log("d"); }, 500);
setTimeout(function () { console.log("e"); }, 500);
console.log("b");
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
var result = [];
load(result);
function load(result) {
setTimeout(function () {
result.concat([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
}, 3000);
};
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
var result;
load(function (data) {
result = data;
});
function load(callback) {
setTimeout(function () {
callback([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
}, 3000);
};
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
init
function init() {
$("#spinner").show();
setup();
$("#spinner").hide();
}
setup
hide
show
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
function init() {
$("#spinner").show();
setTimeout(
function() {
setup();
$("#spinner").hide();
}, 0);
}
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
try {
setTimeout(function () {
throw new Error('Catch me if you can!');
}, 0);
} catch (e) {
console.error(e);
}
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
var worker = {
updateCustomer: function (customerInfo, callback ) { ... }
// other methods, properties, etc
};
worker.updateCustomer( currentCustomer, function (err, data) {
alert(err || data);
// this != worker
});
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
worker.updateCustomer(currentCustomer, function (err, data) {
this.showAlert(err || data);
}.bind(notifier));
// using underscore/lodash
worker.updateCustomer(currentCustomer, _.bind(function (err, data) {
this.showAlert(err || data);
}, notifier));
// using jquery
worker.updateCustomer(currentCustomer, $.proxy(function (err, data) {
this.showAlert(err || data);
}, notifier));
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
worker.updateCustomer(currentCustomer, function (err, data) {
this.showAlert(err || data);
}.bind(notifier));
// using underscore/lodash
worker.updateCustomer(currentCustomer, _.bind(function (err, data) {
this.showAlert(err || data);
}, notifier));
// using jquery
worker.updateCustomer(currentCustomer, $.proxy(function (err, data) {
this.showAlert(err || data);
}, notifier));
var updateForm = {
submit: function () {
// get the data and store it in currentCustomer
worker.updateCustomer(
currentCustomer, this.showAlert.bind(this) );
},
showAlert: function (err, data) {
// I don't care how, just show an alert :-)
}
};
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
for (var i = 0, len = items.length; i < len; i++) {
process(items[i]);
}
function processArray(items, process, callback) {
var todo = items.concat(); //create a clone of the original
setTimeout(function func() {
process(todo.shift());
if (todo.length > 0) {
setTimeout( func, 25 );
} else {
callback(items);
}
}, 25);
}
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
function saveDocument(id) {
//save the document
openDocument(id)
writeText(id);
closeDocument(id);
// update the UI to
// indicate success
updateUI(id);
}
function saveDocument(id) {
processArray(
[
openDocument,
writeText,
closeDocument,
updateUI
]
,function(item){ item(id)}
,function(){}
);
}
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
function timedProcessArray(items, process, callback) {
var todo = items.concat(); //create a clone of the original
setTimeout(function () {
var start = +new Date();
do {
process(todo.shift());
} while (todo.length > 0 && (+new Date() - start < 50));
if ( todo.length > 0 ) {
setTimeout( arguments.callee, 25 );
} else {
callback(items);
}
}, 25 );
}
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
var allTheCustomerThings;
$("#getCustomer").click(function (cust) {
var id = $("#cust-id").val();
getCustomer(id, function (cust) {
allTheCustomerThings = cust;
getContacts(id, function (contacts) {
allTheCustomerThings.contacts = contacts;
getOrders(id, function (orders) {
allTheCustomerThings.orders = orders;
getAccountsRecv(id, function (ar) {
allTheCustomerThings.ar = ar;
// OK - we got all the data, NOW WHAT?! :-)
});
});
});
});
});
“The problem isn’t with the language itself;
it’s with the way programmers use the
language — Async Javascript.”
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
var result;
load(function (data) {
result = data;
});
function load(callback) {
setTimeout(function () {
callback([1, 2, 3]);
}, 3000);
};
function load() {
return new Promise(
function (resolve,reject){
setTimeout(function(){
resolve([1, 2, 3]);
}, 3000);
});
}
var result;
var p = load();
p.then(function (data) {
result = data;
})
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
var p1 = action()
var p2 = p1.then(fs,fe)
var p3 = p2.then(fs,fe) P1
P2
P3
fefs
fefs
fefs
action()
Resolve Reject
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
new Promise(function( resolve, reject) {...})
.then(onFulfilled, onRejected);
Promise
Return one of three:
1. undefined
2. value
3. Promise (fulfilled)
Fulfilled
Return one of two:
1. Exception
2. Promise (rejected)
Rejected
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
// fictional viewmodel for a mobile login screen
// the ugly nested callback version
var loginViewModel = (function () {
var login = function () {
var username = $('#loginUsername').val();
var password = $('#loginPassword').val();
el.Users.login(
username,
password,
function () {
usersModel.load(
function () {
mobileApp.navigate(
'views/notesView.html',
function () { // YAY! We made it! },
function (err) { showError(err.message); });
},
function (err) { showError(err.message); });
},
function (err) { showError(err.message); });
};
}());
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
// Converted to use promises
var loginViewModel = ( function () {
var login = function () {
var username = $('#loginUsername').val();
var password = $('#loginPassword').val();
el.Users.login(username, password)
.then(function () { return usersModel.load(); })
.then(function () { mobileApp.navigate('views/notesView.html');})
.then(
null, // YAY! We made it!
function (err) { showError(err.message); }
);
};
return { login: login };
})();
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
function doAsync() {
var promise = doSomethingAsync();
promise.then(...);
return promise;
}
function doAsync() {
var promise = doSomethingAsync();
return promise.then(...);
}
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
getJSON('story.json')
.then(function(story) {
return getJSON(story.chapterUrls[0]);
})
.then(function(chapter1) {
console.log("Got chapter 1", chapter1);
});
getJSON('story.json')
.then(function(story) {
getJSON(story.chapterUrls[0])
.then(function(chapter1) {
console.log("Got chapter 1", chapter1);
});
});
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
asyncThing1()
.then (function() { return asyncThing2(); })
.then (function() { return asyncThing3(); })
.catch(function(err) { return asyncRecovery1(); })
.then (function() { return asyncThing4(); },
function(err) { return asyncRecovery2(); })
.catch(function(err) { console.log("Don't worry about it"); })
.then (function() { console.log("All done!"); });
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
asyncThing1()
.then (function() { return asyncThing2(); })
.then (function() { return asyncThing3(); })
.catch(function(err) { return asyncRecovery1(); })
.then (function() { return asyncThing4(); },
function(err) { return asyncRecovery2(); })
.catch(function(err) { console.log("Don't worry about it");
})
.then (function() { console.log("All done!"); });
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
var p1 = Promise.resolve(3);
var p2 = 1337;
var p3 = new Promise(function (resolve, reject) {
setTimeout(resolve, 100, "foo");
});
Promise.all([p1, p2, p3])
.then(function (values) {
console.log(values); // [3, 1337, "foo"]
});
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
var p1 = new Promise(function (resolve, reject) {
setTimeout(resolve, 500, "one");
});
var p2 = new Promise(function (resolve, reject) {
setTimeout(resolve, 100, "two");
});
Promise.race([p1, p2]).then(function (value) {
console.log(value); // "two"
// Both resolve, but p2 is faster
});
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
function delay(time) {
return new Promise(function (resolve) {
setTimeout(resolve, time);
});
}
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
function timeout( promise , time ) {
return new Promise(function (fulfill, reject) {
// race promise against delay
promise.then(fulfill, reject);
delay(time).done(function () {
reject(new Error('Operation timed out'));
});
});
}
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
function timeout(promise, time) {
return Promise.race(
[
promise,
delay(time)
.then(function () {
throw new Error('Operation timed out');
})
]);
}
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
loadSomething().then(function(something) {
loadAnotherthing().then(function(another) {
DoSomethingOnThem(something, another);
});
});
q.all([ loadSomething() , loadAnotherThing() ])
.spread(function(something, another) {
DoSomethingOnThem(something, another);
});
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
var allTheCustomerThings;
$("#getCustomer").click(function (cust) {
var id = $("#cust-id").val();
getCustomer(id, function (cust) {
allTheCustomerThings = cust;
getContacts(id, function (contacts) {
allTheCustomerThings.contacts = contacts;
getOrders(id, function (orders) {
allTheCustomerThings.orders = orders;
getAccountsRecv(id, function (ar) {
allTheCustomerThings.ar = ar;
// OK - we got all the data, NOW WHAT?! :-)
});
});
});
});
});
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
$("#getCustomer").click(function (cust) {
var id = $("#cust-id").val();
Q.spread([
getCustomer(id),
getContacts(id),
getOrders(id),
getAccountsRecv(id) ],
function (cust, contacts, orders, ar) {
cust.contacts = contacts;
cust.orders = orders;
cust.ar = ar;
}
);
});
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
function processArray(items, process, callback) {
var todo = items.concat(); //create a clone of the original
setTimeout(function func() {
process(todo.shift());
if (todo.length > 0) {
setTimeout( func, 25 );
} else {
callback(items);
}
}, 25);
}
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
function processArray(items, process) {
return new Promise(function( resolve , reject ){
var todo = items.concat();
setTimeout(function func() {
process(todo.shift());
if (todo.length > 0) {
setTimeout( func, 25 );
} else {
resolve(items);
}
}, 25);
});
}
Process is
async?
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
function processArray(items, process) {
return new Promise(function( resolve , reject ){
var todo = items.concat();
setTimeout(function func() {
process(todo.shift())
.then(function () {
if (todo.length > 0) {
setTimeout( func, 25 );
} else { resolve(items); }
});
}, 25);
});
}
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
// Option I
action();
.then(function(actionResult){});
// Option II
var result = await action();
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
// printDelayed is a 'Promise<void>'
async function printDelayed(elements: string[]) {
for (const element of elements) {
await delay(200);
console.log(element);
}
}
async function delay(milliseconds: number) {
return new Promise<void>(resolve => {
setTimeout(resolve, milliseconds);
});
}
printDelayed(["Hello", "beautiful", "world"]).then(() => {
console.log();
console.log("Printed every element!");
});
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
var result;
load(function (data) {
result = data;
});
function load(callback) {
setTimeout(function () {
callback([1, 2, 3]);
}, 3000);
};
var result;
var p = load();
p.then(function (data) {
result = data;
})
function load() {
var defer = $.Defered();
setTimeout(function () {
defer.resolve([1, 2, 3]);
}, 3000);
return defer.promise();
}
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
var obj = { hello: function (name) {alert(name); } },
defer = $.Deferred();
defer.promise(obj);
defer.resolve("John");
// Use the object as a Promise
obj.done(function (name) { obj.hello(name);})
.hello("Karl");
ListenToEvents (READ)
<< interface >>
Promise
ListenToEvents (READ)
TriggerEvents (WRITE)
<< interface >>
Deferred
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
var serverData = {};
var getting1 = $.get('/1')
.done(function (result) { serverData['1'] = result; });
var getting2 = $.get('/2')
.done(function (result) { serverData['2'] = result; });
$.when(getting1, getting2)
.done(function () {
//the GET information is now in server Data...
});
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
$.ajax("/get/mail/"))
.done( newMessages,
updateMessageList,
updateUnreadIndicator )
.fail(noMessages)
.always(
function () {
var date = new Date();
$("#lastUpdated")
.html( date.toDateString() );
}
);
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
var nanowrimoing = $.Deferred();
var wordGoal = 5000;
nanowrimoing.progress(function (wordCount) {
varpercentComplete = Math.floor(wordCount / wordGoal * 100);
$('#indicator').text(percentComplete + '%complete');
});
nanowrimoing.done(function () {
$('#indicator').text('Goodjob!');
});
$('#document').on('keypress', function () {
var wordCount = $(this).val().split(/s+/).length;
if (wordCount >= wordGoal) {
nanowrimoing.resolve();
};
nanowrimoing.notify(wordCount);
});
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
var worker = new Worker('myThread.js');
worker.addEventListener('message',function(e){console.log(e.data);});
worker.postMessage('input message');
msg
//myThread.js
self.addEventListener( 'message' , doEcho );
function doEcho (e) { self.postMessage('Echo: ' + e.data) };
doEchoEcho
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
// Test if Dedicated Web Workers are available
if (window.Worker) { g_bDedicatedWorkersEnabled = true; }
// Test if Shared Web Workers are available
if (window.SharedWorker) { g_bSharedWorkersEnabled = true; }
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
worker.postMessage(
{data: int8View, moreData: anotherBuffer},
[int8View.buffer, anotherBuffer] );
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
importScripts('script1.js', 'script2.js');
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
 In Chrome, there's a nice page to view all of the created blob
URLs: chrome://blob-internals/
var blob = new Blob([
"onmessage = function(e) { postMessage('msg from worker'); }"]);
// Obtain a blob URL reference to our worker 'file'.
var blobURL = window.URL.createObjectURL(blob);
var worker = new Worker(blobURL);
worker.onmessage = function (e) { // e.data == 'msg from worker' };
worker.postMessage('msg'); // Start the worker
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
function onError(e) {
document.getElementById('error').textContent = [
'ERROR: Line ', e.lineno, ' in ', e.filename, ': ', e.message
].join('');
}
function onMsg(e) { ... }
var worker = new Worker('workerWithError.js');
worker.addEventListener('message', onMsg, false);
worker.addEventListener('error', onError, false);
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
var calculator = operative({
add: function (a, b) {
return a + b;
}
});
// Calc on web worker and return the result to UI thread.
calculator.add(1, 2, function (result) {
result; // => 3
});
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
Observable
Subscribe
Observer
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
function action() {
return $http.get('/someUrl')
.then(function successCallback(response) { },
function errorCallback(response) { }
);
}
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
function action() {
return http.get('/someUrl')
.map(res => res.data.json());
}
action()
.subscribe(onNextFn, onErrorFn, onComplateFn );
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
http://jaredforsyth.com/rxvision/
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
MSFT
27.01
INTC
21.75
MSFT
27.96
MSFT
31.21
INTC
22.54
INTC
20.98
MSFT
30.73
from tick in ticks
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
MSFT
27.01
INTC
21.75
MSFT
27.96
MSFT
31.21
INTC
22.54
INTC
20.98
MSFT
30.73
27.01 27.96 31.21 30.73
21.75 22.54 20.98
from tick in ticks
group tick by tick.Symbol
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
MSFT
27.01
INTC
21.75
MSFT
27.96
MSFT
31.21
INTC
22.54
INTC
20.98
MSFT
30.73
from tick in ticks
group tick by tick.Symbol into company
from openClose in company.Buffer(2, 1)
[27.01, 27.96] [27.96, 31.21] [31.21, 30.73]
[21.75, 22.54] [22.54, 20.98]
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
MSFT
27.01
INTC
21.75
MSFT
27.96
MSFT
31.21
INTC
22.54
INTC
20.98
MSFT
30.73
from tick in ticks
group tick by tick.Symbol into company
from openClose in company.Buffer(2, 1)
let diff = (openClose[1] – openClose[0]) / openClose[0]
0.034 0.104 -0.015
0.036 -0.069
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
MSFT
27.01
INTC
21.75
MSFT
27.96
MSFT
31.21
INTC
22.54
INTC
20.98
MSFT
30.73
from tick in ticks
group tick by tick.Symbol into company
from openClose in company.Buffer(2, 1)
let diff = (openClose[1] – openClose[0]) / openClose[0]
where diff > 0.1
0.034 0.104 -0.015
0.036 -0.069
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
MSFT
27.01
INTC
21.75
MSFT
27.96
MSFT
31.21
INTC
22.54
INTC
20.98
MSFT
30.73
from tick in ticks
group tick by tick.Symbol into company
from openClose in company.Buffer(2, 1)
let diff = (openClose[1] – openClose[0]) / openClose[0]
where diff > 0.1
select new { Company = company.Key, Increase = diff }
Company = MSFT
Increase = 0.104
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
 Autocomplete (source) (demo)
 Canvas Painting (source) (demo)
 Drag and Drop (source) (demo)
 AMD and Require.js Integration (source) (demo)
 Time Flies Like an Arrow (source) (demo)
Link to Start with: Introduction to the Rx for JavaScript
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
Asynchronous JS: Callbacks, Listeners, Control Flow Libs
and Promises
Five Patterns to Help You Tame Asynchronous JavaScript
The basics of Web Workers
How JavaScript Timers Work
http://creativejs.com/resources/requestanimationframe/
© 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: evardi@gmail.com
eyalvardi.wordpress.com
Ad

Recommended

Scope & Functions in ECMAScript 6.0
Scope & Functions in ECMAScript 6.0
Eyal Vardi
 
Iterators & Generators in ECMAScript 6.0
Iterators & Generators in ECMAScript 6.0
Eyal Vardi
 
Objects & Classes in ECMAScript 6.0
Objects & Classes in ECMAScript 6.0
Eyal Vardi
 
Modules in ECMAScript 6.0
Modules in ECMAScript 6.0
Eyal Vardi
 
Proxies in ECMAScript 6.0
Proxies in ECMAScript 6.0
Eyal Vardi
 
Build Lightweight Web Module
Build Lightweight Web Module
Morgan Cheng
 
Is writing performant code too expensive?
Is writing performant code too expensive?
Tomasz Kowalczewski
 
2014_07_28_Django環境安裝以及 Django Book Chapter 4: Templates
2014_07_28_Django環境安裝以及 Django Book Chapter 4: Templates
Ke Wei Louis
 
ngMess: AngularJS Dependency Injection
ngMess: AngularJS Dependency Injection
Dzmitry Ivashutsin
 
Specs Presentation
Specs Presentation
Synesso
 
ES6 patterns in the wild
ES6 patterns in the wild
Joe Morgan
 
Bootiful Development with Spring Boot and React
Bootiful Development with Spring Boot and React
VMware Tanzu
 
My Top 5 APEX JavaScript API's
My Top 5 APEX JavaScript API's
Roel Hartman
 
Demystifying Hooks, Actions & Filters - WordCamp Belfast 2018
Demystifying Hooks, Actions & Filters - WordCamp Belfast 2018
Damien Carbery
 
ES6 Simplified
ES6 Simplified
Carlos Ble
 
누구나 할 수 있다 Networking
누구나 할 수 있다 Networking
Jungwon An
 
Why Redux-Observable?
Why Redux-Observable?
Anna Su
 
Python Yield
Python Yield
yangjuven
 
Testing Services Effectively
Testing Services Effectively
Alberto Leal
 
Programação reativa e o actor model
Programação reativa e o actor model
Fabrício Rissetto
 
#ajn3.lt.marblejenka
#ajn3.lt.marblejenka
Shingo Furuyama
 
Two Trains and Other Refactoring Analogies
Two Trains and Other Refactoring Analogies
Kevin London
 
Programs
Programs
kulwinderbawa007
 
A gremlin in my graph confoo 2014
A gremlin in my graph confoo 2014
Damien Seguy
 
Node js overview
Node js overview
Eyal Vardi
 
Android HttpClient - new slide!
Android HttpClient - new slide!
Chalermchon Samana
 
Angular 2.0 forms
Angular 2.0 forms
Eyal Vardi
 
Angular 2.0 Pipes
Angular 2.0 Pipes
Eyal Vardi
 
Angular 2.0 Routing and Navigation
Angular 2.0 Routing and Navigation
Eyal Vardi
 
Http Communication in Angular 2.0
Http Communication in Angular 2.0
Eyal Vardi
 

More Related Content

What's hot (18)

ngMess: AngularJS Dependency Injection
ngMess: AngularJS Dependency Injection
Dzmitry Ivashutsin
 
Specs Presentation
Specs Presentation
Synesso
 
ES6 patterns in the wild
ES6 patterns in the wild
Joe Morgan
 
Bootiful Development with Spring Boot and React
Bootiful Development with Spring Boot and React
VMware Tanzu
 
My Top 5 APEX JavaScript API's
My Top 5 APEX JavaScript API's
Roel Hartman
 
Demystifying Hooks, Actions & Filters - WordCamp Belfast 2018
Demystifying Hooks, Actions & Filters - WordCamp Belfast 2018
Damien Carbery
 
ES6 Simplified
ES6 Simplified
Carlos Ble
 
누구나 할 수 있다 Networking
누구나 할 수 있다 Networking
Jungwon An
 
Why Redux-Observable?
Why Redux-Observable?
Anna Su
 
Python Yield
Python Yield
yangjuven
 
Testing Services Effectively
Testing Services Effectively
Alberto Leal
 
Programação reativa e o actor model
Programação reativa e o actor model
Fabrício Rissetto
 
#ajn3.lt.marblejenka
#ajn3.lt.marblejenka
Shingo Furuyama
 
Two Trains and Other Refactoring Analogies
Two Trains and Other Refactoring Analogies
Kevin London
 
Programs
Programs
kulwinderbawa007
 
A gremlin in my graph confoo 2014
A gremlin in my graph confoo 2014
Damien Seguy
 
Node js overview
Node js overview
Eyal Vardi
 
Android HttpClient - new slide!
Android HttpClient - new slide!
Chalermchon Samana
 
ngMess: AngularJS Dependency Injection
ngMess: AngularJS Dependency Injection
Dzmitry Ivashutsin
 
Specs Presentation
Specs Presentation
Synesso
 
ES6 patterns in the wild
ES6 patterns in the wild
Joe Morgan
 
Bootiful Development with Spring Boot and React
Bootiful Development with Spring Boot and React
VMware Tanzu
 
My Top 5 APEX JavaScript API's
My Top 5 APEX JavaScript API's
Roel Hartman
 
Demystifying Hooks, Actions & Filters - WordCamp Belfast 2018
Demystifying Hooks, Actions & Filters - WordCamp Belfast 2018
Damien Carbery
 
ES6 Simplified
ES6 Simplified
Carlos Ble
 
누구나 할 수 있다 Networking
누구나 할 수 있다 Networking
Jungwon An
 
Why Redux-Observable?
Why Redux-Observable?
Anna Su
 
Python Yield
Python Yield
yangjuven
 
Testing Services Effectively
Testing Services Effectively
Alberto Leal
 
Programação reativa e o actor model
Programação reativa e o actor model
Fabrício Rissetto
 
Two Trains and Other Refactoring Analogies
Two Trains and Other Refactoring Analogies
Kevin London
 
A gremlin in my graph confoo 2014
A gremlin in my graph confoo 2014
Damien Seguy
 
Node js overview
Node js overview
Eyal Vardi
 
Android HttpClient - new slide!
Android HttpClient - new slide!
Chalermchon Samana
 

Viewers also liked (20)

Angular 2.0 forms
Angular 2.0 forms
Eyal Vardi
 
Angular 2.0 Pipes
Angular 2.0 Pipes
Eyal Vardi
 
Angular 2.0 Routing and Navigation
Angular 2.0 Routing and Navigation
Eyal Vardi
 
Http Communication in Angular 2.0
Http Communication in Angular 2.0
Eyal Vardi
 
Template syntax in Angular 2.0
Template syntax in Angular 2.0
Eyal Vardi
 
Component lifecycle hooks in Angular 2.0
Component lifecycle hooks in Angular 2.0
Eyal Vardi
 
Angular 2.0 Dependency injection
Angular 2.0 Dependency injection
Eyal Vardi
 
Node.js File system & Streams
Node.js File system & Streams
Eyal Vardi
 
Node.js Socket.IO
Node.js Socket.IO
Eyal Vardi
 
Node.js Event Emitter
Node.js Event Emitter
Eyal Vardi
 
Modules and injector
Modules and injector
Eyal Vardi
 
Angular 2.0 Views
Angular 2.0 Views
Eyal Vardi
 
Nodejs
Nodejs
Eyal Vardi
 
Node.js Spplication Scaling
Node.js Spplication Scaling
Eyal Vardi
 
Routing And Navigation
Routing And Navigation
Eyal Vardi
 
Angular 2 NgModule
Angular 2 NgModule
Eyal Vardi
 
Upgrading from Angular 1.x to Angular 2.x
Upgrading from Angular 1.x to Angular 2.x
Eyal Vardi
 
AngulrJS Overview
AngulrJS Overview
Eyal Vardi
 
Angular 2 - Ahead of-time Compilation
Angular 2 - Ahead of-time Compilation
Eyal Vardi
 
Performance Optimization In Angular 2
Performance Optimization In Angular 2
Eyal Vardi
 
Angular 2.0 forms
Angular 2.0 forms
Eyal Vardi
 
Angular 2.0 Pipes
Angular 2.0 Pipes
Eyal Vardi
 
Angular 2.0 Routing and Navigation
Angular 2.0 Routing and Navigation
Eyal Vardi
 
Http Communication in Angular 2.0
Http Communication in Angular 2.0
Eyal Vardi
 
Template syntax in Angular 2.0
Template syntax in Angular 2.0
Eyal Vardi
 
Component lifecycle hooks in Angular 2.0
Component lifecycle hooks in Angular 2.0
Eyal Vardi
 
Angular 2.0 Dependency injection
Angular 2.0 Dependency injection
Eyal Vardi
 
Node.js File system & Streams
Node.js File system & Streams
Eyal Vardi
 
Node.js Socket.IO
Node.js Socket.IO
Eyal Vardi
 
Node.js Event Emitter
Node.js Event Emitter
Eyal Vardi
 
Modules and injector
Modules and injector
Eyal Vardi
 
Angular 2.0 Views
Angular 2.0 Views
Eyal Vardi
 
Node.js Spplication Scaling
Node.js Spplication Scaling
Eyal Vardi
 
Routing And Navigation
Routing And Navigation
Eyal Vardi
 
Angular 2 NgModule
Angular 2 NgModule
Eyal Vardi
 
Upgrading from Angular 1.x to Angular 2.x
Upgrading from Angular 1.x to Angular 2.x
Eyal Vardi
 
AngulrJS Overview
AngulrJS Overview
Eyal Vardi
 
Angular 2 - Ahead of-time Compilation
Angular 2 - Ahead of-time Compilation
Eyal Vardi
 
Performance Optimization In Angular 2
Performance Optimization In Angular 2
Eyal Vardi
 
Ad

Similar to Async & Parallel in JavaScript (20)

What’s new in ECMAScript 6.0
What’s new in ECMAScript 6.0
Eyal Vardi
 
Async & Parallel in JavaScript
Async & Parallel in JavaScript
Eyal Vardi
 
EWD 3 Training Course Part 43: Using JSON Web Tokens with QEWD REST Services
EWD 3 Training Course Part 43: Using JSON Web Tokens with QEWD REST Services
Rob Tweed
 
ES2015 New Features
ES2015 New Features
Giacomo Zinetti
 
GlueCon 2016 - Threading in JavaScript
GlueCon 2016 - Threading in JavaScript
Jonathan Baker
 
OOP in JavaScript
OOP in JavaScript
Eyal Vardi
 
How to test complex SaaS applications - The family july 2014
How to test complex SaaS applications - The family july 2014
Guillaume POTIER
 
TDC 2014 - JavaScript de qualidade: hoje, amanhã e sempre!
TDC 2014 - JavaScript de qualidade: hoje, amanhã e sempre!
Guilherme Carreiro
 
Virtual Madness @ Etsy
Virtual Madness @ Etsy
Nishan Subedi
 
Introduction à CoffeeScript pour ParisRB
Introduction à CoffeeScript pour ParisRB
jhchabran
 
Adding ES6 to Your Developer Toolbox
Adding ES6 to Your Developer Toolbox
Jeff Strauss
 
Forms in AngularJS
Forms in AngularJS
Eyal Vardi
 
R57shell
R57shell
ady36
 
AMD & Require.js
AMD & Require.js
Eyal Vardi
 
Tidy Up Your Code
Tidy Up Your Code
Abbas Ali
 
Como NÃO testar o seu projeto de Software. DevDay 2014
Como NÃO testar o seu projeto de Software. DevDay 2014
alexandre freire
 
Building Modern and Secure PHP Applications – Codementor Office Hours with Be...
Building Modern and Secure PHP Applications – Codementor Office Hours with Be...
Arc & Codementor
 
What's new in ECMAScript 6
What's new in ECMAScript 6
Ran Wahle
 
EWD 3 Training Course Part 13: Putting Everything so far into Practice using ...
EWD 3 Training Course Part 13: Putting Everything so far into Practice using ...
Rob Tweed
 
More than syntax
More than syntax
Wooga
 
What’s new in ECMAScript 6.0
What’s new in ECMAScript 6.0
Eyal Vardi
 
Async & Parallel in JavaScript
Async & Parallel in JavaScript
Eyal Vardi
 
EWD 3 Training Course Part 43: Using JSON Web Tokens with QEWD REST Services
EWD 3 Training Course Part 43: Using JSON Web Tokens with QEWD REST Services
Rob Tweed
 
GlueCon 2016 - Threading in JavaScript
GlueCon 2016 - Threading in JavaScript
Jonathan Baker
 
OOP in JavaScript
OOP in JavaScript
Eyal Vardi
 
How to test complex SaaS applications - The family july 2014
How to test complex SaaS applications - The family july 2014
Guillaume POTIER
 
TDC 2014 - JavaScript de qualidade: hoje, amanhã e sempre!
TDC 2014 - JavaScript de qualidade: hoje, amanhã e sempre!
Guilherme Carreiro
 
Virtual Madness @ Etsy
Virtual Madness @ Etsy
Nishan Subedi
 
Introduction à CoffeeScript pour ParisRB
Introduction à CoffeeScript pour ParisRB
jhchabran
 
Adding ES6 to Your Developer Toolbox
Adding ES6 to Your Developer Toolbox
Jeff Strauss
 
Forms in AngularJS
Forms in AngularJS
Eyal Vardi
 
R57shell
R57shell
ady36
 
AMD & Require.js
AMD & Require.js
Eyal Vardi
 
Tidy Up Your Code
Tidy Up Your Code
Abbas Ali
 
Como NÃO testar o seu projeto de Software. DevDay 2014
Como NÃO testar o seu projeto de Software. DevDay 2014
alexandre freire
 
Building Modern and Secure PHP Applications – Codementor Office Hours with Be...
Building Modern and Secure PHP Applications – Codementor Office Hours with Be...
Arc & Codementor
 
What's new in ECMAScript 6
What's new in ECMAScript 6
Ran Wahle
 
EWD 3 Training Course Part 13: Putting Everything so far into Practice using ...
EWD 3 Training Course Part 13: Putting Everything so far into Practice using ...
Rob Tweed
 
More than syntax
More than syntax
Wooga
 
Ad

More from Eyal Vardi (9)

Why magic
Why magic
Eyal Vardi
 
Smart Contract
Smart Contract
Eyal Vardi
 
Rachel's grandmother's recipes
Rachel's grandmother's recipes
Eyal Vardi
 
Angular 2 Architecture (Bucharest 26/10/2016)
Angular 2 Architecture (Bucharest 26/10/2016)
Eyal Vardi
 
Angular 2 Architecture
Angular 2 Architecture
Eyal Vardi
 
Angular 1.x vs. Angular 2.x
Angular 1.x vs. Angular 2.x
Eyal Vardi
 
Symbols in ECMAScript 6.0
Symbols in ECMAScript 6.0
Eyal Vardi
 
AngularJS Internal
AngularJS Internal
Eyal Vardi
 
Node.js Express
Node.js Express
Eyal Vardi
 
Smart Contract
Smart Contract
Eyal Vardi
 
Rachel's grandmother's recipes
Rachel's grandmother's recipes
Eyal Vardi
 
Angular 2 Architecture (Bucharest 26/10/2016)
Angular 2 Architecture (Bucharest 26/10/2016)
Eyal Vardi
 
Angular 2 Architecture
Angular 2 Architecture
Eyal Vardi
 
Angular 1.x vs. Angular 2.x
Angular 1.x vs. Angular 2.x
Eyal Vardi
 
Symbols in ECMAScript 6.0
Symbols in ECMAScript 6.0
Eyal Vardi
 
AngularJS Internal
AngularJS Internal
Eyal Vardi
 
Node.js Express
Node.js Express
Eyal Vardi
 

Recently uploaded (20)

Complete WordPress Programming Guidance Book
Complete WordPress Programming Guidance Book
Shabista Imam
 
Reimagining Software Development and DevOps with Agentic AI
Reimagining Software Development and DevOps with Agentic AI
Maxim Salnikov
 
The Anti-Masterclass Live - Peak of Data & AI 2025
The Anti-Masterclass Live - Peak of Data & AI 2025
Safe Software
 
Emvigo Capability Deck 2025: Accelerating Innovation Through Intelligent Soft...
Emvigo Capability Deck 2025: Accelerating Innovation Through Intelligent Soft...
Emvigo Technologies
 
SAP PM Module Level-IV Training Complete.ppt
SAP PM Module Level-IV Training Complete.ppt
MuhammadShaheryar36
 
Open Source Software Development Methods
Open Source Software Development Methods
VICTOR MAESTRE RAMIREZ
 
Download Adobe Illustrator Crack free for Windows 2025?
Download Adobe Illustrator Crack free for Windows 2025?
grete1122g
 
Foundations of Marketo Engage - Programs, Campaigns & Beyond - June 2025
Foundations of Marketo Engage - Programs, Campaigns & Beyond - June 2025
BradBedford3
 
Azure AI Foundry: The AI app and agent factory
Azure AI Foundry: The AI app and agent factory
Maxim Salnikov
 
MOVIE RECOMMENDATION SYSTEM, UDUMULA GOPI REDDY, Y24MC13085.pptx
MOVIE RECOMMENDATION SYSTEM, UDUMULA GOPI REDDY, Y24MC13085.pptx
Maharshi Mallela
 
Threat Modeling a Batch Job Framework - Teri Radichel - AWS re:Inforce 2025
Threat Modeling a Batch Job Framework - Teri Radichel - AWS re:Inforce 2025
2nd Sight Lab
 
Zoho Creator Solution for EI by Elsner Technologies.docx
Zoho Creator Solution for EI by Elsner Technologies.docx
Elsner Technologies Pvt. Ltd.
 
Heat Treatment Process Automation in India
Heat Treatment Process Automation in India
Reckers Mechatronics
 
arctitecture application system design os dsa
arctitecture application system design os dsa
za241967
 
Modern Platform Engineering with Choreo - The AI-Native Internal Developer Pl...
Modern Platform Engineering with Choreo - The AI-Native Internal Developer Pl...
WSO2
 
Decipher SEO Solutions for your startup needs.
Decipher SEO Solutions for your startup needs.
mathai2
 
On-Device AI: Is It Time to Go All-In, or Do We Still Need the Cloud?
On-Device AI: Is It Time to Go All-In, or Do We Still Need the Cloud?
Hassan Abid
 
Application Modernization with Choreo - The AI-Native Internal Developer Plat...
Application Modernization with Choreo - The AI-Native Internal Developer Plat...
WSO2
 
OpenChain Webinar - AboutCode - Practical Compliance in One Stack – Licensing...
OpenChain Webinar - AboutCode - Practical Compliance in One Stack – Licensing...
Shane Coughlan
 
Milwaukee Marketo User Group June 2025 - Optimize and Enhance Efficiency - Sm...
Milwaukee Marketo User Group June 2025 - Optimize and Enhance Efficiency - Sm...
BradBedford3
 
Complete WordPress Programming Guidance Book
Complete WordPress Programming Guidance Book
Shabista Imam
 
Reimagining Software Development and DevOps with Agentic AI
Reimagining Software Development and DevOps with Agentic AI
Maxim Salnikov
 
The Anti-Masterclass Live - Peak of Data & AI 2025
The Anti-Masterclass Live - Peak of Data & AI 2025
Safe Software
 
Emvigo Capability Deck 2025: Accelerating Innovation Through Intelligent Soft...
Emvigo Capability Deck 2025: Accelerating Innovation Through Intelligent Soft...
Emvigo Technologies
 
SAP PM Module Level-IV Training Complete.ppt
SAP PM Module Level-IV Training Complete.ppt
MuhammadShaheryar36
 
Open Source Software Development Methods
Open Source Software Development Methods
VICTOR MAESTRE RAMIREZ
 
Download Adobe Illustrator Crack free for Windows 2025?
Download Adobe Illustrator Crack free for Windows 2025?
grete1122g
 
Foundations of Marketo Engage - Programs, Campaigns & Beyond - June 2025
Foundations of Marketo Engage - Programs, Campaigns & Beyond - June 2025
BradBedford3
 
Azure AI Foundry: The AI app and agent factory
Azure AI Foundry: The AI app and agent factory
Maxim Salnikov
 
MOVIE RECOMMENDATION SYSTEM, UDUMULA GOPI REDDY, Y24MC13085.pptx
MOVIE RECOMMENDATION SYSTEM, UDUMULA GOPI REDDY, Y24MC13085.pptx
Maharshi Mallela
 
Threat Modeling a Batch Job Framework - Teri Radichel - AWS re:Inforce 2025
Threat Modeling a Batch Job Framework - Teri Radichel - AWS re:Inforce 2025
2nd Sight Lab
 
Zoho Creator Solution for EI by Elsner Technologies.docx
Zoho Creator Solution for EI by Elsner Technologies.docx
Elsner Technologies Pvt. Ltd.
 
Heat Treatment Process Automation in India
Heat Treatment Process Automation in India
Reckers Mechatronics
 
arctitecture application system design os dsa
arctitecture application system design os dsa
za241967
 
Modern Platform Engineering with Choreo - The AI-Native Internal Developer Pl...
Modern Platform Engineering with Choreo - The AI-Native Internal Developer Pl...
WSO2
 
Decipher SEO Solutions for your startup needs.
Decipher SEO Solutions for your startup needs.
mathai2
 
On-Device AI: Is It Time to Go All-In, or Do We Still Need the Cloud?
On-Device AI: Is It Time to Go All-In, or Do We Still Need the Cloud?
Hassan Abid
 
Application Modernization with Choreo - The AI-Native Internal Developer Plat...
Application Modernization with Choreo - The AI-Native Internal Developer Plat...
WSO2
 
OpenChain Webinar - AboutCode - Practical Compliance in One Stack – Licensing...
OpenChain Webinar - AboutCode - Practical Compliance in One Stack – Licensing...
Shane Coughlan
 
Milwaukee Marketo User Group June 2025 - Optimize and Enhance Efficiency - Sm...
Milwaukee Marketo User Group June 2025 - Optimize and Enhance Efficiency - Sm...
BradBedford3
 

Async & Parallel in JavaScript

  • 1. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 2. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 3. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 4. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] var result = load(); function load() { var data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; return data; };
  • 5. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] function foo() { setTimeout(function fn() { result.concat([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); }, 3000); } foo() fn()
  • 6. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] var start = new Date(); setTimeout(function () { var end = new Date(); console.log('Timeelapsed:', end - start, 'ms'); }, 500); while (new Date() - start < 1000) { }; What will be the result: 1. 500 < result < 1000 2. 1000 < result < 1500 3. 1500 < result
  • 7. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] This API does not guarantee that timers will run exactly on schedule. Delays due to CPU load, other tasks, etc, are to be expected. console.log("a"); setTimeout(function () { console.log("c"); }, 500); setTimeout(function () { console.log("d"); }, 500); setTimeout(function () { console.log("e"); }, 500); console.log("b");
  • 8. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] var result = []; load(result); function load(result) { setTimeout(function () { result.concat([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); }, 3000); };
  • 9. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] var result; load(function (data) { result = data; }); function load(callback) { setTimeout(function () { callback([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); }, 3000); };
  • 10. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 11. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] init function init() { $("#spinner").show(); setup(); $("#spinner").hide(); } setup hide show
  • 12. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] function init() { $("#spinner").show(); setTimeout( function() { setup(); $("#spinner").hide(); }, 0); }
  • 13. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] try { setTimeout(function () { throw new Error('Catch me if you can!'); }, 0); } catch (e) { console.error(e); }
  • 14. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] var worker = { updateCustomer: function (customerInfo, callback ) { ... } // other methods, properties, etc }; worker.updateCustomer( currentCustomer, function (err, data) { alert(err || data); // this != worker });
  • 15. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] worker.updateCustomer(currentCustomer, function (err, data) { this.showAlert(err || data); }.bind(notifier)); // using underscore/lodash worker.updateCustomer(currentCustomer, _.bind(function (err, data) { this.showAlert(err || data); }, notifier)); // using jquery worker.updateCustomer(currentCustomer, $.proxy(function (err, data) { this.showAlert(err || data); }, notifier));
  • 16. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] worker.updateCustomer(currentCustomer, function (err, data) { this.showAlert(err || data); }.bind(notifier)); // using underscore/lodash worker.updateCustomer(currentCustomer, _.bind(function (err, data) { this.showAlert(err || data); }, notifier)); // using jquery worker.updateCustomer(currentCustomer, $.proxy(function (err, data) { this.showAlert(err || data); }, notifier)); var updateForm = { submit: function () { // get the data and store it in currentCustomer worker.updateCustomer( currentCustomer, this.showAlert.bind(this) ); }, showAlert: function (err, data) { // I don't care how, just show an alert :-) } };
  • 17. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] for (var i = 0, len = items.length; i < len; i++) { process(items[i]); } function processArray(items, process, callback) { var todo = items.concat(); //create a clone of the original setTimeout(function func() { process(todo.shift()); if (todo.length > 0) { setTimeout( func, 25 ); } else { callback(items); } }, 25); }
  • 18. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] function saveDocument(id) { //save the document openDocument(id) writeText(id); closeDocument(id); // update the UI to // indicate success updateUI(id); } function saveDocument(id) { processArray( [ openDocument, writeText, closeDocument, updateUI ] ,function(item){ item(id)} ,function(){} ); }
  • 19. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] function timedProcessArray(items, process, callback) { var todo = items.concat(); //create a clone of the original setTimeout(function () { var start = +new Date(); do { process(todo.shift()); } while (todo.length > 0 && (+new Date() - start < 50)); if ( todo.length > 0 ) { setTimeout( arguments.callee, 25 ); } else { callback(items); } }, 25 ); }
  • 20. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 21. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 22. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] var allTheCustomerThings; $("#getCustomer").click(function (cust) { var id = $("#cust-id").val(); getCustomer(id, function (cust) { allTheCustomerThings = cust; getContacts(id, function (contacts) { allTheCustomerThings.contacts = contacts; getOrders(id, function (orders) { allTheCustomerThings.orders = orders; getAccountsRecv(id, function (ar) { allTheCustomerThings.ar = ar; // OK - we got all the data, NOW WHAT?! :-) }); }); }); }); }); “The problem isn’t with the language itself; it’s with the way programmers use the language — Async Javascript.”
  • 23. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] var result; load(function (data) { result = data; }); function load(callback) { setTimeout(function () { callback([1, 2, 3]); }, 3000); }; function load() { return new Promise( function (resolve,reject){ setTimeout(function(){ resolve([1, 2, 3]); }, 3000); }); } var result; var p = load(); p.then(function (data) { result = data; })
  • 24. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 25. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 26. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] var p1 = action() var p2 = p1.then(fs,fe) var p3 = p2.then(fs,fe) P1 P2 P3 fefs fefs fefs action() Resolve Reject
  • 27. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] new Promise(function( resolve, reject) {...}) .then(onFulfilled, onRejected); Promise Return one of three: 1. undefined 2. value 3. Promise (fulfilled) Fulfilled Return one of two: 1. Exception 2. Promise (rejected) Rejected
  • 28. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] // fictional viewmodel for a mobile login screen // the ugly nested callback version var loginViewModel = (function () { var login = function () { var username = $('#loginUsername').val(); var password = $('#loginPassword').val(); el.Users.login( username, password, function () { usersModel.load( function () { mobileApp.navigate( 'views/notesView.html', function () { // YAY! We made it! }, function (err) { showError(err.message); }); }, function (err) { showError(err.message); }); }, function (err) { showError(err.message); }); }; }());
  • 29. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] // Converted to use promises var loginViewModel = ( function () { var login = function () { var username = $('#loginUsername').val(); var password = $('#loginPassword').val(); el.Users.login(username, password) .then(function () { return usersModel.load(); }) .then(function () { mobileApp.navigate('views/notesView.html');}) .then( null, // YAY! We made it! function (err) { showError(err.message); } ); }; return { login: login }; })();
  • 30. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] function doAsync() { var promise = doSomethingAsync(); promise.then(...); return promise; } function doAsync() { var promise = doSomethingAsync(); return promise.then(...); }
  • 31. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] getJSON('story.json') .then(function(story) { return getJSON(story.chapterUrls[0]); }) .then(function(chapter1) { console.log("Got chapter 1", chapter1); }); getJSON('story.json') .then(function(story) { getJSON(story.chapterUrls[0]) .then(function(chapter1) { console.log("Got chapter 1", chapter1); }); });
  • 32. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] asyncThing1() .then (function() { return asyncThing2(); }) .then (function() { return asyncThing3(); }) .catch(function(err) { return asyncRecovery1(); }) .then (function() { return asyncThing4(); }, function(err) { return asyncRecovery2(); }) .catch(function(err) { console.log("Don't worry about it"); }) .then (function() { console.log("All done!"); });
  • 33. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] asyncThing1() .then (function() { return asyncThing2(); }) .then (function() { return asyncThing3(); }) .catch(function(err) { return asyncRecovery1(); }) .then (function() { return asyncThing4(); }, function(err) { return asyncRecovery2(); }) .catch(function(err) { console.log("Don't worry about it"); }) .then (function() { console.log("All done!"); });
  • 34. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] var p1 = Promise.resolve(3); var p2 = 1337; var p3 = new Promise(function (resolve, reject) { setTimeout(resolve, 100, "foo"); }); Promise.all([p1, p2, p3]) .then(function (values) { console.log(values); // [3, 1337, "foo"] });
  • 35. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] var p1 = new Promise(function (resolve, reject) { setTimeout(resolve, 500, "one"); }); var p2 = new Promise(function (resolve, reject) { setTimeout(resolve, 100, "two"); }); Promise.race([p1, p2]).then(function (value) { console.log(value); // "two" // Both resolve, but p2 is faster });
  • 36. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] function delay(time) { return new Promise(function (resolve) { setTimeout(resolve, time); }); }
  • 37. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] function timeout( promise , time ) { return new Promise(function (fulfill, reject) { // race promise against delay promise.then(fulfill, reject); delay(time).done(function () { reject(new Error('Operation timed out')); }); }); }
  • 38. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] function timeout(promise, time) { return Promise.race( [ promise, delay(time) .then(function () { throw new Error('Operation timed out'); }) ]); }
  • 39. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] loadSomething().then(function(something) { loadAnotherthing().then(function(another) { DoSomethingOnThem(something, another); }); }); q.all([ loadSomething() , loadAnotherThing() ]) .spread(function(something, another) { DoSomethingOnThem(something, another); });
  • 40. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 41. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] var allTheCustomerThings; $("#getCustomer").click(function (cust) { var id = $("#cust-id").val(); getCustomer(id, function (cust) { allTheCustomerThings = cust; getContacts(id, function (contacts) { allTheCustomerThings.contacts = contacts; getOrders(id, function (orders) { allTheCustomerThings.orders = orders; getAccountsRecv(id, function (ar) { allTheCustomerThings.ar = ar; // OK - we got all the data, NOW WHAT?! :-) }); }); }); }); });
  • 42. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] $("#getCustomer").click(function (cust) { var id = $("#cust-id").val(); Q.spread([ getCustomer(id), getContacts(id), getOrders(id), getAccountsRecv(id) ], function (cust, contacts, orders, ar) { cust.contacts = contacts; cust.orders = orders; cust.ar = ar; } ); });
  • 43. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] function processArray(items, process, callback) { var todo = items.concat(); //create a clone of the original setTimeout(function func() { process(todo.shift()); if (todo.length > 0) { setTimeout( func, 25 ); } else { callback(items); } }, 25); }
  • 44. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] function processArray(items, process) { return new Promise(function( resolve , reject ){ var todo = items.concat(); setTimeout(function func() { process(todo.shift()); if (todo.length > 0) { setTimeout( func, 25 ); } else { resolve(items); } }, 25); }); } Process is async?
  • 45. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] function processArray(items, process) { return new Promise(function( resolve , reject ){ var todo = items.concat(); setTimeout(function func() { process(todo.shift()) .then(function () { if (todo.length > 0) { setTimeout( func, 25 ); } else { resolve(items); } }); }, 25); }); }
  • 46. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] // Option I action(); .then(function(actionResult){}); // Option II var result = await action();
  • 47. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] // printDelayed is a 'Promise<void>' async function printDelayed(elements: string[]) { for (const element of elements) { await delay(200); console.log(element); } } async function delay(milliseconds: number) { return new Promise<void>(resolve => { setTimeout(resolve, milliseconds); }); } printDelayed(["Hello", "beautiful", "world"]).then(() => { console.log(); console.log("Printed every element!"); });
  • 48. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 49. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 50. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] var result; load(function (data) { result = data; }); function load(callback) { setTimeout(function () { callback([1, 2, 3]); }, 3000); }; var result; var p = load(); p.then(function (data) { result = data; }) function load() { var defer = $.Defered(); setTimeout(function () { defer.resolve([1, 2, 3]); }, 3000); return defer.promise(); }
  • 51. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] var obj = { hello: function (name) {alert(name); } }, defer = $.Deferred(); defer.promise(obj); defer.resolve("John"); // Use the object as a Promise obj.done(function (name) { obj.hello(name);}) .hello("Karl"); ListenToEvents (READ) << interface >> Promise ListenToEvents (READ) TriggerEvents (WRITE) << interface >> Deferred
  • 52. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] var serverData = {}; var getting1 = $.get('/1') .done(function (result) { serverData['1'] = result; }); var getting2 = $.get('/2') .done(function (result) { serverData['2'] = result; }); $.when(getting1, getting2) .done(function () { //the GET information is now in server Data... });
  • 53. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] $.ajax("/get/mail/")) .done( newMessages, updateMessageList, updateUnreadIndicator ) .fail(noMessages) .always( function () { var date = new Date(); $("#lastUpdated") .html( date.toDateString() ); } );
  • 54. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] var nanowrimoing = $.Deferred(); var wordGoal = 5000; nanowrimoing.progress(function (wordCount) { varpercentComplete = Math.floor(wordCount / wordGoal * 100); $('#indicator').text(percentComplete + '%complete'); }); nanowrimoing.done(function () { $('#indicator').text('Goodjob!'); }); $('#document').on('keypress', function () { var wordCount = $(this).val().split(/s+/).length; if (wordCount >= wordGoal) { nanowrimoing.resolve(); }; nanowrimoing.notify(wordCount); });
  • 55. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 56. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 57. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 58. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] var worker = new Worker('myThread.js'); worker.addEventListener('message',function(e){console.log(e.data);}); worker.postMessage('input message'); msg //myThread.js self.addEventListener( 'message' , doEcho ); function doEcho (e) { self.postMessage('Echo: ' + e.data) }; doEchoEcho
  • 59. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] // Test if Dedicated Web Workers are available if (window.Worker) { g_bDedicatedWorkersEnabled = true; } // Test if Shared Web Workers are available if (window.SharedWorker) { g_bSharedWorkersEnabled = true; }
  • 60. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 61. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 62. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] worker.postMessage( {data: int8View, moreData: anotherBuffer}, [int8View.buffer, anotherBuffer] );
  • 63. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] importScripts('script1.js', 'script2.js');
  • 64. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected]  In Chrome, there's a nice page to view all of the created blob URLs: chrome://blob-internals/ var blob = new Blob([ "onmessage = function(e) { postMessage('msg from worker'); }"]); // Obtain a blob URL reference to our worker 'file'. var blobURL = window.URL.createObjectURL(blob); var worker = new Worker(blobURL); worker.onmessage = function (e) { // e.data == 'msg from worker' }; worker.postMessage('msg'); // Start the worker
  • 65. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] function onError(e) { document.getElementById('error').textContent = [ 'ERROR: Line ', e.lineno, ' in ', e.filename, ': ', e.message ].join(''); } function onMsg(e) { ... } var worker = new Worker('workerWithError.js'); worker.addEventListener('message', onMsg, false); worker.addEventListener('error', onError, false);
  • 66. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 67. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 68. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 69. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] var calculator = operative({ add: function (a, b) { return a + b; } }); // Calc on web worker and return the result to UI thread. calculator.add(1, 2, function (result) { result; // => 3 });
  • 70. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 71. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 72. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] Observable Subscribe Observer
  • 73. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] function action() { return $http.get('/someUrl') .then(function successCallback(response) { }, function errorCallback(response) { } ); }
  • 74. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] function action() { return http.get('/someUrl') .map(res => res.data.json()); } action() .subscribe(onNextFn, onErrorFn, onComplateFn );
  • 75. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] http://jaredforsyth.com/rxvision/
  • 76. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] MSFT 27.01 INTC 21.75 MSFT 27.96 MSFT 31.21 INTC 22.54 INTC 20.98 MSFT 30.73 from tick in ticks
  • 77. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] MSFT 27.01 INTC 21.75 MSFT 27.96 MSFT 31.21 INTC 22.54 INTC 20.98 MSFT 30.73 27.01 27.96 31.21 30.73 21.75 22.54 20.98 from tick in ticks group tick by tick.Symbol
  • 78. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] MSFT 27.01 INTC 21.75 MSFT 27.96 MSFT 31.21 INTC 22.54 INTC 20.98 MSFT 30.73 from tick in ticks group tick by tick.Symbol into company from openClose in company.Buffer(2, 1) [27.01, 27.96] [27.96, 31.21] [31.21, 30.73] [21.75, 22.54] [22.54, 20.98]
  • 79. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] MSFT 27.01 INTC 21.75 MSFT 27.96 MSFT 31.21 INTC 22.54 INTC 20.98 MSFT 30.73 from tick in ticks group tick by tick.Symbol into company from openClose in company.Buffer(2, 1) let diff = (openClose[1] – openClose[0]) / openClose[0] 0.034 0.104 -0.015 0.036 -0.069
  • 80. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] MSFT 27.01 INTC 21.75 MSFT 27.96 MSFT 31.21 INTC 22.54 INTC 20.98 MSFT 30.73 from tick in ticks group tick by tick.Symbol into company from openClose in company.Buffer(2, 1) let diff = (openClose[1] – openClose[0]) / openClose[0] where diff > 0.1 0.034 0.104 -0.015 0.036 -0.069
  • 81. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] MSFT 27.01 INTC 21.75 MSFT 27.96 MSFT 31.21 INTC 22.54 INTC 20.98 MSFT 30.73 from tick in ticks group tick by tick.Symbol into company from openClose in company.Buffer(2, 1) let diff = (openClose[1] – openClose[0]) / openClose[0] where diff > 0.1 select new { Company = company.Key, Increase = diff } Company = MSFT Increase = 0.104
  • 82. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected]  Autocomplete (source) (demo)  Canvas Painting (source) (demo)  Drag and Drop (source) (demo)  AMD and Require.js Integration (source) (demo)  Time Flies Like an Arrow (source) (demo) Link to Start with: Introduction to the Rx for JavaScript
  • 83. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] Asynchronous JS: Callbacks, Listeners, Control Flow Libs and Promises Five Patterns to Help You Tame Asynchronous JavaScript The basics of Web Workers How JavaScript Timers Work http://creativejs.com/resources/requestanimationframe/
  • 84. © 2016 Eyal Vardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] eyalvardi.wordpress.com