33
Asynchrony in JavaScript Alper Sarikaya (@yelperalp) CS 638 JavaScript & Web Programming November 17 th , 2015

Asychronicity in JavaScript - University of Wisconsin ...pages.cs.wisc.edu/~sarikaya/content/classlecture-js-async.pdf · Handling Asynchronicity Want to (without reloading page):

  • Upload
    others

  • View
    3

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Asychronicity in JavaScript - University of Wisconsin ...pages.cs.wisc.edu/~sarikaya/content/classlecture-js-async.pdf · Handling Asynchronicity Want to (without reloading page):

Asynchrony in JavaScript

Alper Sarikaya (@yelperalp)CS 638 JavaScript & Web Programming

November 17th, 2015

Page 2: Asychronicity in JavaScript - University of Wisconsin ...pages.cs.wisc.edu/~sarikaya/content/classlecture-js-async.pdf · Handling Asynchronicity Want to (without reloading page):

Asynchrony in JavaScript

How we handle it in JavaScript (and jQuery, D3, etc.)

Requesting data in JavaScript (and jQuery, D3, etc.)

Event Handling (and jQuery, D3, etc.)

Reactive Programming

WebSockets/binary data/WebGL

WebWorkers -

Page 3: Asychronicity in JavaScript - University of Wisconsin ...pages.cs.wisc.edu/~sarikaya/content/classlecture-js-async.pdf · Handling Asynchronicity Want to (without reloading page):
Page 4: Asychronicity in JavaScript - University of Wisconsin ...pages.cs.wisc.edu/~sarikaya/content/classlecture-js-async.pdf · Handling Asynchronicity Want to (without reloading page):
Page 5: Asychronicity in JavaScript - University of Wisconsin ...pages.cs.wisc.edu/~sarikaya/content/classlecture-js-async.pdf · Handling Asynchronicity Want to (without reloading page):

JavaScript is single-threaded!

This means:

Asynchronous events can return and interrupt

Long processing work can block interrupts from occurring (page appears to hang)

Only one thing can be done at a time(except if you use WebWorkers; more later)

Page 6: Asychronicity in JavaScript - University of Wisconsin ...pages.cs.wisc.edu/~sarikaya/content/classlecture-js-async.pdf · Handling Asynchronicity Want to (without reloading page):

Handling Asynchronicity

Want to (without reloading page):

Get data from datastore on the webserver

Update state on webserver based on user action

Post a message, record a vote for others to see

Retrieve some video/binary data to display to client

Page 7: Asychronicity in JavaScript - University of Wisconsin ...pages.cs.wisc.edu/~sarikaya/content/classlecture-js-async.pdf · Handling Asynchronicity Want to (without reloading page):

Handling Asynchronicity

Make an XmlHttpRequest (XHR)

Ajax programming model

Asynchronous JavaScript and XML

Page 8: Asychronicity in JavaScript - University of Wisconsin ...pages.cs.wisc.edu/~sarikaya/content/classlecture-js-async.pdf · Handling Asynchronicity Want to (without reloading page):

var xhr = new XMLHttpRequest();xhr.open('GET', 'DoSomething.php', true);xhr.responseType = 'json';

xhr.addEventListener('load', function() {if (xhr.status == 200) {

loadBinaryData(xhr.response);} else {

console.warning("failed to load (status: %d)", xhr.status);

console.trace();}

});

xhr.send(null);

Page 9: Asychronicity in JavaScript - University of Wisconsin ...pages.cs.wisc.edu/~sarikaya/content/classlecture-js-async.pdf · Handling Asynchronicity Want to (without reloading page):

var xhr = new XMLHttpRequest();xhr.open('GET', 'DoSomething.php', true);xhr.responseType = 'json';

xhr.addEventListener('load', function() {if (xhr.status == 200) {

loadJsonData(xhr.response);} else {

console.warning("failed to load (status: %d)", xhr.status);

console.trace();}

});

xhr.send(null);

Webserver does a task

Type of returned data

Do something with the returned data

Send the request

https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest

Page 10: Asychronicity in JavaScript - University of Wisconsin ...pages.cs.wisc.edu/~sarikaya/content/classlecture-js-async.pdf · Handling Asynchronicity Want to (without reloading page):

$.get('DoSomething.php', loadJsonData, 'json');

https://api.jquery.com/jquery.get/

Page 11: Asychronicity in JavaScript - University of Wisconsin ...pages.cs.wisc.edu/~sarikaya/content/classlecture-js-async.pdf · Handling Asynchronicity Want to (without reloading page):

$.get('DoSomething.php', loadJsonData, 'json');

https://api.jquery.com/jquery.get/

One success

Implement JavaScript operations in a cross-browser way

Syntactic sugar (do the same thing in less lines of code)

JavaScript ECMA 5 (basically HTML5) standardized a lot of the ugly old stuff

Page 12: Asychronicity in JavaScript - University of Wisconsin ...pages.cs.wisc.edu/~sarikaya/content/classlecture-js-async.pdf · Handling Asynchronicity Want to (without reloading page):

Dealing with returned data

$.get('DoSomething.php', loadJsonData, 'json');

Do something with the returned data

Page 13: Asychronicity in JavaScript - University of Wisconsin ...pages.cs.wisc.edu/~sarikaya/content/classlecture-js-async.pdf · Handling Asynchronicity Want to (without reloading page):

Dealing with returned data

Do something with the returned data

var dataReady = false;var ds = {};

$.get('DoSomething.php', loadJsonData, 'json');var loadJsonData = function(text) {dataReady = false;ds.data = [];

// process some data, fill up ds.data with text

// Set flag to allow rendering to continue.dataReady = true;

};

Page 14: Asychronicity in JavaScript - University of Wisconsin ...pages.cs.wisc.edu/~sarikaya/content/classlecture-js-async.pdf · Handling Asynchronicity Want to (without reloading page):

Dealing with returned data

Do something with the returned data

$.get('DoSomething.php', loadJsonData, 'json');$.get('DoSomethingElse.php', loadJsonData, 'json');var loadJsonData = function(text) {dataReady = false;ds.data = [];

// process some data, fill up ds.data with text

// Set flag to allow rendering to continue.// ???dataReady = true;

};

Page 15: Asychronicity in JavaScript - University of Wisconsin ...pages.cs.wisc.edu/~sarikaya/content/classlecture-js-async.pdf · Handling Asynchronicity Want to (without reloading page):

Dealing with returned data

Do something with the returned data

var loadJsonFile = function(text) {// process the data

continueIfDone();};

var continueIfDone = function() {// check that all data is loaded, if not:return false;

// otherwise, continuenextStep();

}

Page 16: Asychronicity in JavaScript - University of Wisconsin ...pages.cs.wisc.edu/~sarikaya/content/classlecture-js-async.pdf · Handling Asynchronicity Want to (without reloading page):

Use promises for one-time callbacks (built into ES6: http://www.html5rocks.com/en/tutorials/es6/promises/)

Use WebSockets for real-time connections (e.g. chat)(built into newer browsers, see https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_client_applications for an example)

Page 17: Asychronicity in JavaScript - University of Wisconsin ...pages.cs.wisc.edu/~sarikaya/content/classlecture-js-async.pdf · Handling Asynchronicity Want to (without reloading page):

Promises!

getJSON('story.json').then(function(story) {return getJSON(story.chapterUrls[0]);

}).then(function(chapter1) {console.log("Got chapter 1!", chapter1);

});

http://www.html5rocks.com/en/tutorials/es6/promises/

Page 18: Asychronicity in JavaScript - University of Wisconsin ...pages.cs.wisc.edu/~sarikaya/content/classlecture-js-async.pdf · Handling Asynchronicity Want to (without reloading page):

Promises!function get(url) {// Return a new promise.return new Promise(function(resolve, reject) {// Do the usual XHR stuffvar req = new XMLHttpRequest();req.open('GET', url);

req.onload = function() {// This is called even on 404 etc// so check the statusif (req.status == 200) {// Resolve the promise with the response textresolve(req.response);

}else {// Otherwise reject with the status text// which will hopefully be a meaningful errorreject(Error(req.statusText));

}};

// Handle network errorsreq.onerror = function() {reject(Error("Network Error"));

};

// Make the requestreq.send();

});}

Page 19: Asychronicity in JavaScript - University of Wisconsin ...pages.cs.wisc.edu/~sarikaya/content/classlecture-js-async.pdf · Handling Asynchronicity Want to (without reloading page):

Processing Data

Very convenient to deal with JSON dataJust set returnType json

arraybuffer

{"VHA4_P11_F21_DPI3-ref": {"attenuation":

"readBreadth.dat","metrics": "conjProbDiff.dat","numReads": 258000,"reference": "VN1203-HA.fa.txt"

},"VHA3_P1_F991_DPI3-ref": {"attenuation":

"readBreadth.dat","metrics": "conjProbDiff.dat","numReads": 295000,"reference": "VN1203-HA.fa.txt"

}}

Page 20: Asychronicity in JavaScript - University of Wisconsin ...pages.cs.wisc.edu/~sarikaya/content/classlecture-js-async.pdf · Handling Asynchronicity Want to (without reloading page):

var xhr = new XMLHttpRequest();xhr.open('GET', 'DoSomething.php', true);xhr.responseType = 'json';

xhr.addEventListener('load', function() {if (xhr.status == 200) {

loadJsonData(xhr.response);} else {

console.warning("failed to load (status: %d)", xhr.status);

console.trace();}

});

xhr.send(null);

Bind to event!

Event Listeners

Page 21: Asychronicity in JavaScript - University of Wisconsin ...pages.cs.wisc.edu/~sarikaya/content/classlecture-js-async.pdf · Handling Asynchronicity Want to (without reloading page):

Event Listeners

Events can be:

Monitoring AJAX progress events (see Monitoring Progress on MDN)

User input (mouseover, mousemove, key-press)

Custom-built events (e.g. when a rendering pass finishes)

Page 22: Asychronicity in JavaScript - University of Wisconsin ...pages.cs.wisc.edu/~sarikaya/content/classlecture-js-async.pdf · Handling Asynchronicity Want to (without reloading page):
Page 23: Asychronicity in JavaScript - University of Wisconsin ...pages.cs.wisc.edu/~sarikaya/content/classlecture-js-async.pdf · Handling Asynchronicity Want to (without reloading page):

Applications?

Validating formsAre all parameters within acceptable values?

Navigating page with keystrokesEver typed in ? into Twitter or Gmail?

Capture user inputUser can drive a WebGL game, drag DOM elements, etc.

Page 24: Asychronicity in JavaScript - University of Wisconsin ...pages.cs.wisc.edu/~sarikaya/content/classlecture-js-async.pdf · Handling Asynchronicity Want to (without reloading page):

<button id="submit" type="submit">Submit Form</button>

Event Listeners

var submitButton = document.getElementById("#submit");

submitButton.addEventListener("click", parseForm);

HTML

JS

Page 25: Asychronicity in JavaScript - University of Wisconsin ...pages.cs.wisc.edu/~sarikaya/content/classlecture-js-async.pdf · Handling Asynchronicity Want to (without reloading page):

<button id="submit" type="submit">Submit Form</button>

Event Listeners (jQuery)

$("#submit").click(parseForm);

HTML

JS

Page 26: Asychronicity in JavaScript - University of Wisconsin ...pages.cs.wisc.edu/~sarikaya/content/classlecture-js-async.pdf · Handling Asynchronicity Want to (without reloading page):

<div id="container"><button id="submit" type="submit">Submit Form</button>

</div>

Multiple Event Listeners in DOM

$("#submit").click(parseForm);$("#container").click(doSomethingElse);

HTML

JS

parseForm() called

doSomethingElse() called

Page 27: Asychronicity in JavaScript - University of Wisconsin ...pages.cs.wisc.edu/~sarikaya/content/classlecture-js-async.pdf · Handling Asynchronicity Want to (without reloading page):

<div id="container"><button id="submit" type="submit">Submit Form</button>

</div>

Multiple Event Listeners in DOM

$("#submit").click(parseForm);$("#container").click(doSomethingElse);var parseForm = function(event) {event.stopPropagation();// pull data from the form, and parse

};

HTML

JS

Page 28: Asychronicity in JavaScript - University of Wisconsin ...pages.cs.wisc.edu/~sarikaya/content/classlecture-js-async.pdf · Handling Asynchronicity Want to (without reloading page):

Alternatives?

Reactive programming style (Rx)See https://gist.github.com/staltz/868e7e9bc2a7b8c1f754 for a great intro

Page 29: Asychronicity in JavaScript - University of Wisconsin ...pages.cs.wisc.edu/~sarikaya/content/classlecture-js-async.pdf · Handling Asynchronicity Want to (without reloading page):

Asynchrony Potpourrivar dataWorker = new Worker('worker.js');dataWorker.postMessage(numPoints);console.log("sent message");

dataWorker.onmessage = function(e) {console.log("received response");

};WebWorkers uses a message-passingsystem to offload computation intoa separate thread.This gets around the UI hanging issuewhen processing data!

onmessage = function(e) {var numPoints = e.data;// do some computation

postMessage(['databuf', returnData], returnData);}worker.js

Page 30: Asychronicity in JavaScript - University of Wisconsin ...pages.cs.wisc.edu/~sarikaya/content/classlecture-js-async.pdf · Handling Asynchronicity Want to (without reloading page):

Asynchrony Potpourrivar xhr = new XMLHttpRequest();xhr.open('GET', filename, true);xhr.responseType = 'arraybuffer';

xhr.addEventListener('progress', updateProgress(name), false);

xhr.addEventListener('load', function() {if (xhr.status == 200) {loadBinaryData(xhr.response, name);

} else {console.warning("failed to load (status: %d)", xhr.status);console.trace();

}});

xhr.send(null);

Binary data DataView

or natively with WebGL data buffers

Page 31: Asychronicity in JavaScript - University of Wisconsin ...pages.cs.wisc.edu/~sarikaya/content/classlecture-js-async.pdf · Handling Asynchronicity Want to (without reloading page):

Asynchrony Potpourri

function webGLStart() {var canvas = document.getElementById("lesson01-canvas");initGL(canvas);initShaders();initBuffers();

gl.clearColor(0.0, 0.0, 0.0, 1.0);gl.enable(gl.DEPTH_TEST);

drawScene();}

WebGL uses commands sent to the GPU, and eventually fires

Page 32: Asychronicity in JavaScript - University of Wisconsin ...pages.cs.wisc.edu/~sarikaya/content/classlecture-js-async.pdf · Handling Asynchronicity Want to (without reloading page):

Asynchrony Potpourri

function tick() {window.reqeustAnimationFrame(tick);handleKeys();drawScene();animate();

}

RequestAnimationFrame requeststhe browser to call the animationloop as soon as it is able

Page 33: Asychronicity in JavaScript - University of Wisconsin ...pages.cs.wisc.edu/~sarikaya/content/classlecture-js-async.pdf · Handling Asynchronicity Want to (without reloading page):

Asynchrony Potpourri

var exampleSocket = new WebSocket("ws://www.example.com/socketserver", ["protocolOne", "protocolTwo"]);

exampleSocket.send("Here's some text that the server wants!");

exampleSocket.onmessage = function (event) {console.log(event.data);

}

WebSockets use TCP connectionsto send and receive data(think chat applications, real-time connection to server applications...)