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

© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
// plain, non-jQuery version of hooking up an event handler
var clickity = document.getElementById("clickity");
clickity.addEventListener("click", function (e) {
//console log, since it's like ALL real world scenarios, amirite?
console.log("Alas, someone is pressing my buttons…");
});
// the obligatory jQuery version
$("#clickity").on("click", function (e) {
console.log("Alas, someone is pressing my buttons…");
});
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
link.onclick = function () {
clickHandler1.apply(this, arguments);
clickHandler2.apply(this, arguments);
};
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
$('input[type=submit]')
.on('click', function () { console.log('foo'); })
.trigger('click');
console.log('bar');
The output is:
foo
bar
whenever a jQuery event fires, all of its handlers will be executed sequentially
without interruption.
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
$('#tabby,#socks').on('meow', function () {
console.log(this.id + 'meowed');
});
$('#tabby').trigger('meow'); //"tabby meowed"
$('#socks').trigger('meow'); //"socks meowed"
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
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
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
console.log("a");
setTimeout(function () { console.log("c"); }, 500);
setTimeout(function () { console.log("d"); }, 500);
setTimeout(function () { console.log("e"); }, 500);
console.log("b");
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
init
function init() {
$("#spinner").show();
setup();
$("#spinner").hide();
}
setup
hide
show
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
function init() {
$("#spinner").show();
setTimeout(
function() {
setup();
$("#spinner").hide();
}, 0);
}
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
try {
setTimeout(function () {
throw new Error('Catch me if you can!');
}, 0);
} catch (e) {
console.error(e);
}
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
Option I:
$.get('/data', {
success: successHandler,
failure: failureHandler
});
Option II
$.get('/data', function(error, value){
if(error) {
alert('error');
returen; // Don’t forget this !
}
});
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
var worker = {
updateCustomer: function (customerInfo, callback ) { ... }
// other methods, properties, etc
};
worker.updateCustomer( currentCustomer, function (err, data) {
alert(err || data);
// this != worker
});
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
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));
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
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 :-)
}
};
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
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 () {
process(todo.shift());
if (todo.length > 0) {
setTimeout( arguments.callee, 25 );
} else {
callback(items);
}
}, 25);
}
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
function saveDocument(id) {
//save the document
openDocument(id)
writeText(id);
closeDocument(id);
// update the UI to
// indicate success
updateUI(id);
}
function saveDocument(id) {
var tasks =[openDocument,
writeText,
closeDocument,
updateUI];
setTimeout(function () {
//execute the next task
var task = tasks.shift();
task(id);
//determine if there's more
if( tasks.length > 0) {
setTimeout(arguments.callee, 25);
}
}, 25);
}
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
function multistep(steps, args, callback){
var tasks = steps.concat(); //clone the array
setTimeout(function(){
//execute the next task
var task = tasks.shift();
task.apply(null, args || []);
//determine if there's more
if (tasks.length > 0) {
setTimeout(arguments.callee, 25);
} else {
callback();
}
}, 25);
}
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
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 );
}
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
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?! :-)
});
});
});
});
});
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
$.get('/mydata', {
success: onSuccess,
failure: onFailure,
always: onAlways
});
var promise = $.get('/mydata');
promise.done(onSuccess);
promise.fail(onFailure);
promise.always(onAlways);
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
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
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
step1(function (value1) {
step2(value1, function (value2) {
step3(value2, function (value3) {
step4(value3, function (value4) {
// Do something with value4
});
});
});
}); Q.fcall(promisedStep1)
.then(promisedStep2)
.then(promisedStep3)
.then(promisedStep4)
.then(function (value4) {
// Do something with value4 })
.catch(function (error) {
// Handle any error from all above steps
})
.done();
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
// 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); });
};
}());
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
// 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 };
})();
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
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...
});
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
$.when($.ajax("/get/mail/"))
.done( newMessages,
updateMessageList,
updateUnreadIndicator )
.fail(noMessages)
.always(
function () {
var date = new Date();
$("#lastUpdated")
.html( date.toDateString() );
}
);
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
function buildpage() {
return $.Deferred(function (dfd) {
dfd
.pipe(function() { return $('header').fadeIn(); })
.pipe(function() { return $('#main' ).fadeIn(); })
.pipe(function() { return $('footer').fadeIn(); });
}).resolve();
}
$.when( buildpage() )
.done(function() { console.log('done'); } );
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
varnanowrimoing = $.Deferred();
varwordGoal = 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);
});
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
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?! :-)
});
});
});
});
});
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
$("#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;
}
);
});
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
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
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
// 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; }
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
worker.postMessage(
{data: int8View, moreData: anotherBuffer},
[int8View.buffer, anotherBuffer] );
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
importScripts('script1.js', 'script2.js');
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
 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
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
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);
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
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
});
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
when.map(srcs, loadImage)
.then(
function gotEm(imageArray) {
doFancyStuffWithImages(imageArray);
return imageArray.length; },
function doh(err) { handleError(err); } )
.then(
function shout(count) {
// This will happen after gotEm() and count
// is the value returned by gotEm()
alert('see my new ' + count + ' images?'); }
);
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
http://code.dougneiner.com/presentations/machina/
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
Observable
Subscribe
Observer
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
function CreateObservable(element, eventType) {
return Rx.Observable.create(
function (observer) {
function eventHandler(eventObj) {
observer.onNext(eventObj);
}
// keep simple for this example and ignore
// addEventListener/attachEvent browser differences
element.addEventListener(eventType, eventHandler);
return function () {
element.removeEventListener(eventType, eventHandler);
};
});
};
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
var observable =
CreateObservable( document.getElementById('button'), 'click')
.skip(2)
.take(2)
.select(function (evt) { return "button clicked"; });
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
var observer = Rx.Observer.create(
//onNext
function(evt){ alert(evt);},
//onError
function(err){ alert('error');},
//onComplete
function (){ alert('done'); }
);
observable.subscribe(observer);
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
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
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
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
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
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]
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
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
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
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
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
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
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
 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
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
function draw() { // Drawing code goes here }
setInterval(draw, 100);
function draw() {
setTimeout(draw, 100);
// Drawing code goes here
}
draw();
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
function draw() {
requestAnimationFrame(draw);
// Drawing code goes here
}
draw();
The frame rate
of your browser
and
computer, but
typically it’s
60fps.
The key difference here is
that you are requesting
the browser to draw your
animation at the next
available
opportunity, not at a
predetermined interval.
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
polyfill
var fps = 15;
function draw() {
setTimeout(function () {
requestAnimationFrame(draw);
// Drawing code goes here
}, 1000 / fps);
}
Frame rate
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
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/
© 2013 E4D LTD. All rights reserved. Tel: 054-5-767-300, Email: Eyal@E4D.co.il
eyalvardi.wordpress.com

Async & Parallel in JavaScript

  • 1.
    © 2013 E4DLTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 2.
    © 2013 E4DLTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 3.
    © 2013 E4DLTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 4.
    © 2013 E4DLTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected] // plain, non-jQuery version of hooking up an event handler var clickity = document.getElementById("clickity"); clickity.addEventListener("click", function (e) { //console log, since it's like ALL real world scenarios, amirite? console.log("Alas, someone is pressing my buttons…"); }); // the obligatory jQuery version $("#clickity").on("click", function (e) { console.log("Alas, someone is pressing my buttons…"); });
  • 5.
    © 2013 E4DLTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 6.
    © 2013 E4DLTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 7.
    © 2013 E4DLTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected] link.onclick = function () { clickHandler1.apply(this, arguments); clickHandler2.apply(this, arguments); };
  • 8.
    © 2013 E4DLTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected] $('input[type=submit]') .on('click', function () { console.log('foo'); }) .trigger('click'); console.log('bar'); The output is: foo bar whenever a jQuery event fires, all of its handlers will be executed sequentially without interruption.
  • 9.
    © 2013 E4DLTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected] $('#tabby,#socks').on('meow', function () { console.log(this.id + 'meowed'); }); $('#tabby').trigger('meow'); //"tabby meowed" $('#socks').trigger('meow'); //"socks meowed"
  • 10.
    © 2013 E4DLTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 11.
    © 2013 E4DLTD. 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
  • 12.
    © 2013 E4DLTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected] console.log("a"); setTimeout(function () { console.log("c"); }, 500); setTimeout(function () { console.log("d"); }, 500); setTimeout(function () { console.log("e"); }, 500); console.log("b");
  • 13.
    © 2013 E4DLTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected] init function init() { $("#spinner").show(); setup(); $("#spinner").hide(); } setup hide show
  • 14.
    © 2013 E4DLTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected] function init() { $("#spinner").show(); setTimeout( function() { setup(); $("#spinner").hide(); }, 0); }
  • 15.
    © 2013 E4DLTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 16.
    © 2013 E4DLTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 17.
    © 2013 E4DLTD. 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); }
  • 18.
    © 2013 E4DLTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected] Option I: $.get('/data', { success: successHandler, failure: failureHandler }); Option II $.get('/data', function(error, value){ if(error) { alert('error'); returen; // Don’t forget this ! } });
  • 19.
    © 2013 E4DLTD. 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 });
  • 20.
    © 2013 E4DLTD. 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));
  • 21.
    © 2013 E4DLTD. 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 :-) } };
  • 22.
    © 2013 E4DLTD. 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 () { process(todo.shift()); if (todo.length > 0) { setTimeout( arguments.callee, 25 ); } else { callback(items); } }, 25); }
  • 23.
    © 2013 E4DLTD. 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) { var tasks =[openDocument, writeText, closeDocument, updateUI]; setTimeout(function () { //execute the next task var task = tasks.shift(); task(id); //determine if there's more if( tasks.length > 0) { setTimeout(arguments.callee, 25); } }, 25); }
  • 24.
    © 2013 E4DLTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected] function multistep(steps, args, callback){ var tasks = steps.concat(); //clone the array setTimeout(function(){ //execute the next task var task = tasks.shift(); task.apply(null, args || []); //determine if there's more if (tasks.length > 0) { setTimeout(arguments.callee, 25); } else { callback(); } }, 25); }
  • 25.
    © 2013 E4DLTD. 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 ); }
  • 26.
    © 2013 E4DLTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 27.
    © 2013 E4DLTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 28.
    © 2013 E4DLTD. 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?! :-) }); }); }); }); });
  • 29.
    © 2013 E4DLTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected] $.get('/mydata', { success: onSuccess, failure: onFailure, always: onAlways }); var promise = $.get('/mydata'); promise.done(onSuccess); promise.fail(onFailure); promise.always(onAlways);
  • 30.
    © 2013 E4DLTD. 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
  • 31.
    © 2013 E4DLTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected] step1(function (value1) { step2(value1, function (value2) { step3(value2, function (value3) { step4(value3, function (value4) { // Do something with value4 }); }); }); }); Q.fcall(promisedStep1) .then(promisedStep2) .then(promisedStep3) .then(promisedStep4) .then(function (value4) { // Do something with value4 }) .catch(function (error) { // Handle any error from all above steps }) .done();
  • 32.
    © 2013 E4DLTD. 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); }); }; }());
  • 33.
    © 2013 E4DLTD. 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 }; })();
  • 34.
    © 2013 E4DLTD. 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... });
  • 35.
    © 2013 E4DLTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected] $.when($.ajax("/get/mail/")) .done( newMessages, updateMessageList, updateUnreadIndicator ) .fail(noMessages) .always( function () { var date = new Date(); $("#lastUpdated") .html( date.toDateString() ); } );
  • 36.
    © 2013 E4DLTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 37.
    © 2013 E4DLTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected] function buildpage() { return $.Deferred(function (dfd) { dfd .pipe(function() { return $('header').fadeIn(); }) .pipe(function() { return $('#main' ).fadeIn(); }) .pipe(function() { return $('footer').fadeIn(); }); }).resolve(); } $.when( buildpage() ) .done(function() { console.log('done'); } );
  • 38.
    © 2013 E4DLTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected] varnanowrimoing = $.Deferred(); varwordGoal = 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); });
  • 39.
    © 2013 E4DLTD. 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?! :-) }); }); }); }); });
  • 40.
    © 2013 E4DLTD. 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; } ); });
  • 41.
    © 2013 E4DLTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 42.
    © 2013 E4DLTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 43.
    © 2013 E4DLTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 44.
    © 2013 E4DLTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 45.
    © 2013 E4DLTD. 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
  • 46.
    © 2013 E4DLTD. 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; }
  • 47.
    © 2013 E4DLTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 48.
    © 2013 E4DLTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 49.
    © 2013 E4DLTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected] worker.postMessage( {data: int8View, moreData: anotherBuffer}, [int8View.buffer, anotherBuffer] );
  • 50.
    © 2013 E4DLTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected] importScripts('script1.js', 'script2.js');
  • 51.
    © 2013 E4DLTD. 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
  • 52.
    © 2013 E4DLTD. 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);
  • 53.
    © 2013 E4DLTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 54.
    © 2013 E4DLTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 55.
    © 2013 E4DLTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 56.
    © 2013 E4DLTD. 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 });
  • 57.
    © 2013 E4DLTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 58.
    © 2013 E4DLTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 59.
    © 2013 E4DLTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 60.
    © 2013 E4DLTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 61.
    © 2013 E4DLTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 62.
    © 2013 E4DLTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected] when.map(srcs, loadImage) .then( function gotEm(imageArray) { doFancyStuffWithImages(imageArray); return imageArray.length; }, function doh(err) { handleError(err); } ) .then( function shout(count) { // This will happen after gotEm() and count // is the value returned by gotEm() alert('see my new ' + count + ' images?'); } );
  • 63.
    © 2013 E4DLTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 64.
    © 2013 E4DLTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 65.
    © 2013 E4DLTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected] http://code.dougneiner.com/presentations/machina/
  • 66.
    © 2013 E4DLTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 67.
    © 2013 E4DLTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 68.
    © 2013 E4DLTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected] Observable Subscribe Observer
  • 69.
    © 2013 E4DLTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected] function CreateObservable(element, eventType) { return Rx.Observable.create( function (observer) { function eventHandler(eventObj) { observer.onNext(eventObj); } // keep simple for this example and ignore // addEventListener/attachEvent browser differences element.addEventListener(eventType, eventHandler); return function () { element.removeEventListener(eventType, eventHandler); }; }); };
  • 70.
    © 2013 E4DLTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected] var observable = CreateObservable( document.getElementById('button'), 'click') .skip(2) .take(2) .select(function (evt) { return "button clicked"; });
  • 71.
    © 2013 E4DLTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected] var observer = Rx.Observer.create( //onNext function(evt){ alert(evt);}, //onError function(err){ alert('error');}, //onComplete function (){ alert('done'); } ); observable.subscribe(observer);
  • 72.
    © 2013 E4DLTD. 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
  • 73.
    © 2013 E4DLTD. 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
  • 74.
    © 2013 E4DLTD. 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]
  • 75.
    © 2013 E4DLTD. 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
  • 76.
    © 2013 E4DLTD. 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
  • 77.
    © 2013 E4DLTD. 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
  • 78.
    © 2013 E4DLTD. 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
  • 79.
    © 2013 E4DLTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected] function draw() { // Drawing code goes here } setInterval(draw, 100); function draw() { setTimeout(draw, 100); // Drawing code goes here } draw();
  • 80.
    © 2013 E4DLTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected] function draw() { requestAnimationFrame(draw); // Drawing code goes here } draw(); The frame rate of your browser and computer, but typically it’s 60fps. The key difference here is that you are requesting the browser to draw your animation at the next available opportunity, not at a predetermined interval.
  • 81.
    © 2013 E4DLTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected] polyfill var fps = 15; function draw() { setTimeout(function () { requestAnimationFrame(draw); // Drawing code goes here }, 1000 / fps); } Frame rate
  • 82.
    © 2013 E4DLTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected]
  • 83.
    © 2013 E4DLTD. 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.
    © 2013 E4DLTD. All rights reserved. Tel: 054-5-767-300, Email: [email protected] eyalvardi.wordpress.com