tech friday 22.01.2016
TRANSCRIPT
Asynchronous JavaScriptAnssi Kinnunen (@anssikin)
Tech friday 22.01.2016
Asynchrony (programming):
“Refers to the occurrence of events independently of the main
program flow”
https://en.wikipedia.org/wiki/Asynchrony_(computer_programming)
JavaScript● Event loop -based concurrency model
● Almost all I/O is non-blocking
● Single thread, ask runtime to perform operation, provide
callback and move on to other tasks
https://developer.mozilla.org/en/docs/Web/JavaScript/EventLoop
http://blog.carbonfive.com/2013/10/27/the-javascript-event-loop-explained/
http://www.2ality.com/2014/09/es6-promises-foundations.html
JavaScript runtime● Contains a message queue
● Each message is associated with a callback function
● $(‘.btn’).click((evt) => { … })
○ Click (external event) causes message to be queued
https://developer.mozilla.org/en/docs/Web/JavaScript/EventLoophttp://blog.carbonfive.com/2013/10/27/the-javascript-event-loop-explained/
http://www.2ality.com/2014/09/es6-promises-foundations.html
http://stackoverflow.com/a/14797071
JavaScript event loop● Synchronously processes message queue
● Each message is processed completely before others
○ When callback returns, event loop continues
● window.setTimeout(cb, wait)
https://developer.mozilla.org/en/docs/Web/JavaScript/EventLoop
http://blog.carbonfive.com/2013/10/27/the-javascript-event-loop-explained/
http://www.2ality.com/2014/09/es6-promises-foundations.html
function () {
console.log('this is the start');
window.setTimeout(() => {
console.log('this is a msg from call back');
});
console.log('this is just a message');
window.setTimeout(() => {
console.log('this is a msg from call back1');
}, 0);
console.log('this is the end');
}
JavaScript event loop● Browser tab is controlled by a single process
● UI, other computations
● Blocking the event queue?
https://developer.mozilla.org/en/docs/Web/JavaScript/EventLoop
http://blog.carbonfive.com/2013/10/27/the-javascript-event-loop-explained/
http://www.2ality.com/2014/09/es6-promises-foundations.html
Web Workers● API designed to allow running scripts in background
threads
● Worker has separate message queue, event loop and
memory space, independent from originating thread
https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers
http://blog.carbonfive.com/2013/10/27/the-javascript-event-loop-explained/
https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers
http://blog.carbonfive.com/2013/10/27/the-javascript-event-loop-explained/
// pi_calculator.js
let reportResult = (e) => {
let pi = computePiToSpecifiedDecimals(e.data);
postMessage(pi);
};
onmessage = reportResult;
// main code
let piWorker = new Worker(‘pi_calculator.js’);
let logResult = (e) => {
console.log(`PI: ${e.data}`);
};
piWorker.addEventListener(‘message’, logResult, false);
piWorker.postMessage(100000);
ES6: Promise
Promise● Represents (‘proxy’) operation that hasn’t completed yet
● Promise is always in one of three states○ Pending: result has not been computed, yet
○ Fulfilled: result was computed succesfully
○ Rejected: failure occurred during computation
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
http://www.2ality.com/2014/10/es6-promises-api.html
Promise● Promise.all( [ ] ), Promise.race( [ ] )
● Chaining: then() and catch() return promises
○ Promise() -> then() -> then() -> catch()
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
http://www.2ality.com/2014/10/es6-promises-api.html
let doHeavyCalculation = (a, b) => {
return new Promise((resolve, reject) => {
console.log('wait 2000ms');
window.setTimeout(() => {
resolve(a + b);
}, 2000);
});
};
doHeavyCalculation(4, 4).then((result) => {
return doHeavyCalculation(result, 2);
}).then((calculatedValue) => {
console.log(`the result is ${calculatedValue}`);
});
http://www.2ality.com/2014/10/es6-promises-api.html
// Node.js style async file reading
fs.readFile(‘config.json’, (error, text) => {
if (error) {
console.error(‘Error while reading config file’);
} else {
try {
let obj = JSON.parse(text);
console.log(JSON.stringify(obj, null, 4));
} catch (e) {
console.error(‘Invalid JSON in file’);
}
}
});
// Same functionality with promises
readFilePromisified(‘config.json’)
.then((text) => {
let obj = JSON.parse(text);
console.log(JSON.stringify(obj, null, 4));
})
.catch((reason) => {
console.error(`An error occurred ${reason}`);
});
ES7: Async/Await
const request = require('request'); function getQuote() { return new Promise((resolve, reject) => { let url = 'http://ron-swanson-quotes.herokuapp.com/v2/quotes'; request(url, (error, response, quote) => { if (error) { reject(error); } else { resolve(quote); } }); });} async function main() { try { let quote = await getQuote(); console.log(quote); } catch (e) { console.error(e); }}
main();
https://www.twilio.com/blog/2015/10/asyncawait-the-hero-javascript-deserved.html
AJAXAsynchronous JavaScript and XML
AJAX● Group of technologies for async web
○ HTML/CSS, XML/XSLT, DOM
● Data passed is usually JSON
XHRXMLHttpRequest
let request;// Old compatibility code, no longer needed.if (window.XMLHttpRequest) { // Mozilla, Safari, IE7+ ... request = new XMLHttpRequest();} else if (window.ActiveXObject) { // IE 6 and older request = new ActiveXObject("Microsoft.XMLHTTP");}
request.onreadystatechange = () => { if (request.readyState === 4 && request.status === 200) { console.log(request.responseText); }}
request.open('GET', 'http://davidwalsh.name/ajax-endpoint', true);request.send(null);
https://davidwalsh.name/xmlhttprequest
https://developer.mozilla.org/en-US/docs/AJAX/Getting_Started
$.get({ url: 'http://davidwalsh.name/ajax-endpoint', success: function(response) { console.log(response); }});
Fetch API
https://developer.mozilla.org/en/docs/Web/API/Fetch_API
Fetch● Interface for fetching resources, not finalized yet
● Like XHR, but more powerful
● window.fetch() -> Promise() -> Response
// Chaining for more "advanced" handling
fetch('/some/url').then((response) => {
return //...
}).then((returnedValue) => {
// ...
}).catch((err) => {
// Error :(
});
https://www.twilio.com/blog/2015/10/asyncawait-the-hero-javascript-deserved.html