Thanks to visit codestin.com
Credit goes to www.slideshare.net

© 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

Async & Parallel in JavaScript

  • 1.
    © 2016 EyalVardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 2.
    © 2016 EyalVardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 3.
    © 2016 EyalVardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 4.
    © 2016 EyalVardi. 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 EyalVardi. 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 EyalVardi. 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 EyalVardi. 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 EyalVardi. 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 EyalVardi. 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 EyalVardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 11.
    © 2016 EyalVardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] init function init() { $("#spinner").show(); setup(); $("#spinner").hide(); } setup hide show
  • 12.
    © 2016 EyalVardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] function init() { $("#spinner").show(); setTimeout( function() { setup(); $("#spinner").hide(); }, 0); }
  • 13.
    © 2016 EyalVardi. 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 EyalVardi. 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 EyalVardi. 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 EyalVardi. 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 EyalVardi. 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 EyalVardi. 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 EyalVardi. 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 EyalVardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 21.
    © 2016 EyalVardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 22.
    © 2016 EyalVardi. 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 EyalVardi. 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 EyalVardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 25.
    © 2016 EyalVardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 26.
    © 2016 EyalVardi. 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 EyalVardi. 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 EyalVardi. 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 EyalVardi. 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 EyalVardi. 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 EyalVardi. 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 EyalVardi. 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 EyalVardi. 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 EyalVardi. 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 EyalVardi. 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 EyalVardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] function delay(time) { return new Promise(function (resolve) { setTimeout(resolve, time); }); }
  • 37.
    © 2016 EyalVardi. 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 EyalVardi. 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 EyalVardi. 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 EyalVardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 41.
    © 2016 EyalVardi. 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 EyalVardi. 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 EyalVardi. 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 EyalVardi. 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 EyalVardi. 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 EyalVardi. 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 EyalVardi. 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 EyalVardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 49.
    © 2016 EyalVardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 50.
    © 2016 EyalVardi. 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 EyalVardi. 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 EyalVardi. 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 EyalVardi. 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 EyalVardi. 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 EyalVardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 56.
    © 2016 EyalVardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 57.
    © 2016 EyalVardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 58.
    © 2016 EyalVardi. 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 EyalVardi. 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 EyalVardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 61.
    © 2016 EyalVardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 62.
    © 2016 EyalVardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] worker.postMessage( {data: int8View, moreData: anotherBuffer}, [int8View.buffer, anotherBuffer] );
  • 63.
    © 2016 EyalVardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] importScripts('script1.js', 'script2.js');
  • 64.
    © 2016 EyalVardi. 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 EyalVardi. 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 EyalVardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 67.
    © 2016 EyalVardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 68.
    © 2016 EyalVardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 69.
    © 2016 EyalVardi. 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 EyalVardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 71.
    © 2016 EyalVardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 72.
    © 2016 EyalVardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] Observable Subscribe Observer
  • 73.
    © 2016 EyalVardi. 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 EyalVardi. 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 EyalVardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] http://jaredforsyth.com/rxvision/
  • 76.
    © 2016 EyalVardi. 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 EyalVardi. 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 EyalVardi. 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 EyalVardi. 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 EyalVardi. 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 EyalVardi. 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 EyalVardi. 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 EyalVardi. 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 EyalVardi. All rights reserved. Tel: 054-5-767-300, Email: [email protected] eyalvardi.wordpress.com