Top Banner
SWE 432 -Web Application Development Dr. Kevin Moran George Mason University Fall 2021 Week 3: Asynchronous Programming
166

SWE 432 -Web Application Week 3: Development Asynchronous ...

Dec 06, 2021

Download

Documents

dariahiddleston
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: SWE 432 -Web Application Week 3: Development Asynchronous ...

SWE 432 -WebApplication

Development

Dr. Kevin Moran

George MasonUniversity

Fall 2021

Week 3: AsynchronousProgramming

Page 2: SWE 432 -Web Application Week 3: Development Asynchronous ...

Administrivia

•HW Assignment 1 - Due Today Before Class

•HW Assignment 2 - Out on Thursday, will discuss next class

•Quiz #2: Discussion

2

Page 3: SWE 432 -Web Application Week 3: Development Asynchronous ...

Quiz #2 Review

3

Given the code snippet below, write code that will log myProp to the console.

Page 4: SWE 432 -Web Application Week 3: Development Asynchronous ...

Quiz #2 Review

3

console.log(“MyProp: " + object.baz.myProp)

Output: “MyProp: 12”

Given the code snippet below, write code that will log myProp to the console.

Page 5: SWE 432 -Web Application Week 3: Development Asynchronous ...

Quiz #2 Review

4

Given the code snippet below, using a template literal to access the value of the first (zeroth) element, print the message “Population of ”, and log the name

and population of each element.

Page 6: SWE 432 -Web Application Week 3: Development Asynchronous ...

Quiz #2 Review

4

console.log(`Population of ${cities[0].name}: ${cities[0].population}`);

output: “Population of Fairfax: 24574”

Given the code snippet below, using a template literal to access the value of the first (zeroth) element, print the message “Population of ”, and log the name

and population of each element.

Page 7: SWE 432 -Web Application Week 3: Development Asynchronous ...

Quiz #2 Review

5

What is the output of the code snippet listed below?

Page 8: SWE 432 -Web Application Week 3: Development Asynchronous ...

Quiz #2 Review

5

Output: “7 12”

What is the output of the code snippet listed below?

Page 9: SWE 432 -Web Application Week 3: Development Asynchronous ...

Review: Closures

• Closures are expressions that work with variables in a specific context • Closures contain a function, and its needed state

• Closure is a stack frame that is allocated when a function starts executing and not freed after the function returns

• That state just refers to that state by name (sees updates)

6

Page 10: SWE 432 -Web Application Week 3: Development Asynchronous ...

Review: Closures

• Closures are expressions that work with variables in a specific context • Closures contain a function, and its needed state

• Closure is a stack frame that is allocated when a function starts executing and not freed after the function returns

• That state just refers to that state by name (sees updates)

6

var x = 1; function f() { var y = 2; return function() {

console.log(x + y); y++; }; } var g = f(); g(); // 1+2 is 3 g(); // 1+3 is 4

Page 11: SWE 432 -Web Application Week 3: Development Asynchronous ...

Review: Closures

• Closures are expressions that work with variables in a specific context • Closures contain a function, and its needed state

• Closure is a stack frame that is allocated when a function starts executing and not freed after the function returns

• That state just refers to that state by name (sees updates)

6

var x = 1; function f() { var y = 2; return function() {

console.log(x + y); y++; }; } var g = f(); g(); // 1+2 is 3 g(); // 1+3 is 4

This function attaches itself to x and y so that it can continue to access them.

Page 12: SWE 432 -Web Application Week 3: Development Asynchronous ...

Review: Closures

• Closures are expressions that work with variables in a specific context • Closures contain a function, and its needed state

• Closure is a stack frame that is allocated when a function starts executing and not freed after the function returns

• That state just refers to that state by name (sees updates)

6

var x = 1; function f() { var y = 2; return function() {

console.log(x + y); y++; }; } var g = f(); g(); // 1+2 is 3 g(); // 1+3 is 4

This function attaches itself to x and y so that it can continue to access them.

Page 13: SWE 432 -Web Application Week 3: Development Asynchronous ...

Review: Closures

• Closures are expressions that work with variables in a specific context • Closures contain a function, and its needed state

• Closure is a stack frame that is allocated when a function starts executing and not freed after the function returns

• That state just refers to that state by name (sees updates)

6

var x = 1; function f() { var y = 2; return function() {

console.log(x + y); y++; }; } var g = f(); g(); // 1+2 is 3 g(); // 1+3 is 4

This function attaches itself to x and y so that it can continue to access them.

It “closes up” those references

Page 14: SWE 432 -Web Application Week 3: Development Asynchronous ...

Closures

7

Page 15: SWE 432 -Web Application Week 3: Development Asynchronous ...

var x = 1; function f() { var y = 2; return function() {

console.log(x + y); y++; }; } var g = f(); g(); // 1+2 is 3 g(); // 1+3 is 4

Closures

7

Page 16: SWE 432 -Web Application Week 3: Development Asynchronous ...

var x = 1; function f() { var y = 2; return function() {

console.log(x + y); y++; }; } var g = f(); g(); // 1+2 is 3 g(); // 1+3 is 4

Closures

7

Page 17: SWE 432 -Web Application Week 3: Development Asynchronous ...

var x = 1; function f() { var y = 2; return function() {

console.log(x + y); y++; }; } var g = f(); g(); // 1+2 is 3 g(); // 1+3 is 4

Closures

7

f()

var x

var y

function

Global

Closure

1

2

Page 18: SWE 432 -Web Application Week 3: Development Asynchronous ...

var x = 1; function f() { var y = 2; return function() {

console.log(x + y); y++; }; } var g = f(); g(); // 1+2 is 3 g(); // 1+3 is 4

Closures

8

f()

var x

var y

function

Page 19: SWE 432 -Web Application Week 3: Development Asynchronous ...

var x = 1; function f() { var y = 2; return function() {

console.log(x + y); y++; }; } var g = f(); g(); // 1+2 is 3 g(); // 1+3 is 4

Closures

8

f()

var x

var y

function

1

3

Global

Closure

Page 20: SWE 432 -Web Application Week 3: Development Asynchronous ...

var x = 1; function f() { var y = 2; return function() {

console.log(x + y); y++; }; } var g = f(); g(); // 1+2 is 3 g(); // 1+3 is 4

Closures

9

f()

var x

var y

function

Page 21: SWE 432 -Web Application Week 3: Development Asynchronous ...

var x = 1; function f() { var y = 2; return function() {

console.log(x + y); y++; }; } var g = f(); g(); // 1+2 is 3 g(); // 1+3 is 4

Closures

9

f()

var x

var y

function

1

4

Global

Closure

Page 22: SWE 432 -Web Application Week 3: Development Asynchronous ...

Class Overview

10

Page 23: SWE 432 -Web Application Week 3: Development Asynchronous ...

Class Overview

•Part 1 - Asynchronous Programming I: Communicating between

web app components?

•10 minute Break

•Part 2 - Asynchronous Programming II: More communication

strategies

•Part 3 - In-Class Activity: Exploring Asynchronous Programming

11

Page 24: SWE 432 -Web Application Week 3: Development Asynchronous ...

Asynchronous Programming I

12

Page 25: SWE 432 -Web Application Week 3: Development Asynchronous ...

Lecture 1

•What is asynchronous programming? •What are threads? •Writing asynchronous code

13

For further reading:

• Using Promises: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises • Node.js event loop: https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/

Page 26: SWE 432 -Web Application Week 3: Development Asynchronous ...

Why Asynchronous?

• Maintain an interactive application while still doing stuff

• Processing data

• Communicating with remote hosts

• Timers that countdown while our app is running

• Anytime that an app is doing more than one thing at a time, it is asynchronous

14

Page 27: SWE 432 -Web Application Week 3: Development Asynchronous ...

What is a thread?

15

Program execution: a series of sequential method calls ( s)

Page 28: SWE 432 -Web Application Week 3: Development Asynchronous ...

What is a thread?

15

App Starts

App Ends

Program execution: a series of sequential method calls ( s)

Page 29: SWE 432 -Web Application Week 3: Development Asynchronous ...

What is a Thread?

16

App Starts

App Ends

Program execution: a series of sequential method calls ( s)

Multiple threads can run at once -> allows for asynchronous code

Page 30: SWE 432 -Web Application Week 3: Development Asynchronous ...

What is a Thread?

16

App Starts

App Ends

Program execution: a series of sequential method calls ( s)

Multiple threads can run at once -> allows for asynchronous code

Page 31: SWE 432 -Web Application Week 3: Development Asynchronous ...

Multi-Threading in Java

• Multi-Threading allows us to do more than one thing at a time

• Physically, through multiple cores and/or OS scheduler

• Example: Process data while interacting with user

17

Page 32: SWE 432 -Web Application Week 3: Development Asynchronous ...

Multi-Threading in Java

• Multi-Threading allows us to do more than one thing at a time

• Physically, through multiple cores and/or OS scheduler

• Example: Process data while interacting with user

17

main

thread 0

Interacts with userDraws Swing interface

on screen, updates screen

Page 33: SWE 432 -Web Application Week 3: Development Asynchronous ...

Multi-Threading in Java

• Multi-Threading allows us to do more than one thing at a time

• Physically, through multiple cores and/or OS scheduler

• Example: Process data while interacting with user

17

main

thread 0

Interacts with userDraws Swing interface

on screen, updates screen

worker

thread 1

Processes data, generates results

Page 34: SWE 432 -Web Application Week 3: Development Asynchronous ...

Multi-Threading in Java

• Multi-Threading allows us to do more than one thing at a time

• Physically, through multiple cores and/or OS scheduler

• Example: Process data while interacting with user

17

main

thread 0

Interacts with userDraws Swing interface

on screen, updates screen

worker

thread 1

Processes data, generates results

Share data

Signal each other

Page 35: SWE 432 -Web Application Week 3: Development Asynchronous ...

Woes of Multi-Threading

18

public static int v;public static void thread1(){

v = 4;System.out.println(v);

}

public static void thread2(){

v = 2;}

This is a data race: the println in thread1 might see either 2 OR 4

Page 36: SWE 432 -Web Application Week 3: Development Asynchronous ...

Woes of Multi-Threading

18

Thread 1 Thread 2

public static int v;public static void thread1(){

v = 4;System.out.println(v);

}

public static void thread2(){

v = 2;}

This is a data race: the println in thread1 might see either 2 OR 4

Page 37: SWE 432 -Web Application Week 3: Development Asynchronous ...

Woes of Multi-Threading

18

Thread 1 Thread 2

Write V = 4

public static int v;public static void thread1(){

v = 4;System.out.println(v);

}

public static void thread2(){

v = 2;}

This is a data race: the println in thread1 might see either 2 OR 4

Page 38: SWE 432 -Web Application Week 3: Development Asynchronous ...

Woes of Multi-Threading

18

Thread 1 Thread 2

Write V = 4

Write V = 2

public static int v;public static void thread1(){

v = 4;System.out.println(v);

}

public static void thread2(){

v = 2;}

This is a data race: the println in thread1 might see either 2 OR 4

Page 39: SWE 432 -Web Application Week 3: Development Asynchronous ...

Woes of Multi-Threading

18

Thread 1 Thread 2

Write V = 4

Write V = 2

Read V (2)

public static int v;public static void thread1(){

v = 4;System.out.println(v);

}

public static void thread2(){

v = 2;}

This is a data race: the println in thread1 might see either 2 OR 4

Page 40: SWE 432 -Web Application Week 3: Development Asynchronous ...

Woes of Multi-Threading

18

Thread 1 Thread 2

Write V = 4

Write V = 2

Read V (2)

Thread 1 Thread 2

public static int v;public static void thread1(){

v = 4;System.out.println(v);

}

public static void thread2(){

v = 2;}

This is a data race: the println in thread1 might see either 2 OR 4

Page 41: SWE 432 -Web Application Week 3: Development Asynchronous ...

Woes of Multi-Threading

18

Thread 1 Thread 2

Write V = 4

Write V = 2

Read V (2)

Thread 1 Thread 2

Write V = 2

public static int v;public static void thread1(){

v = 4;System.out.println(v);

}

public static void thread2(){

v = 2;}

This is a data race: the println in thread1 might see either 2 OR 4

Page 42: SWE 432 -Web Application Week 3: Development Asynchronous ...

Woes of Multi-Threading

18

Thread 1 Thread 2

Write V = 4

Write V = 2

Read V (2)

Thread 1 Thread 2

Write V = 2

Write V = 4

public static int v;public static void thread1(){

v = 4;System.out.println(v);

}

public static void thread2(){

v = 2;}

This is a data race: the println in thread1 might see either 2 OR 4

Page 43: SWE 432 -Web Application Week 3: Development Asynchronous ...

Woes of Multi-Threading

18

Thread 1 Thread 2

Write V = 4

Write V = 2

Read V (2)

Thread 1 Thread 2

Write V = 2

Write V = 4

Read V (4)

public static int v;public static void thread1(){

v = 4;System.out.println(v);

}

public static void thread2(){

v = 2;}

This is a data race: the println in thread1 might see either 2 OR 4

Page 44: SWE 432 -Web Application Week 3: Development Asynchronous ...

Multi-Threading in JS

19

var request = require(‘request'); request('http://www.google.com', function (error, response, body) { console.log("Heard back from Google!"); }); console.log("Made request");

Request is an asynchronous call

Page 45: SWE 432 -Web Application Week 3: Development Asynchronous ...

Multi-Threading in JS

19

var request = require(‘request'); request('http://www.google.com', function (error, response, body) { console.log("Heard back from Google!"); }); console.log("Made request");

Made requestHeard back from Google!

Output:

Request is an asynchronous call

Page 46: SWE 432 -Web Application Week 3: Development Asynchronous ...

Multi-Threading in JS

• Everything you write will run in a single thread* (event loop)

• Since you are not sharing data between threads, races don’t happen as easily

• Inside of JS engine: many threads

• Event loop processes events, and calls your callbacks

20

thread 1 thread 2 thread 3 thread n…JS Engine

event looper

Page 47: SWE 432 -Web Application Week 3: Development Asynchronous ...

Multi-Threading in JS

• Everything you write will run in a single thread* (event loop)

• Since you are not sharing data between threads, races don’t happen as easily

• Inside of JS engine: many threads

• Event loop processes events, and calls your callbacks

20

thread 1 thread 2 thread 3 thread n…JS Engine

event looperevent loop

Page 48: SWE 432 -Web Application Week 3: Development Asynchronous ...

Multi-Threading in JS

• Everything you write will run in a single thread* (event loop)

• Since you are not sharing data between threads, races don’t happen as easily

• Inside of JS engine: many threads

• Event loop processes events, and calls your callbacks

20

thread 1 thread 2 thread 3 thread n…JS Engine

event looperevent loop

All of your code runs in this one thread

Page 49: SWE 432 -Web Application Week 3: Development Asynchronous ...

Multi-Threading in JS

• Everything you write will run in a single thread* (event loop)

• Since you are not sharing data between threads, races don’t happen as easily

• Inside of JS engine: many threads

• Event loop processes events, and calls your callbacks

20

thread 1 thread 2 thread 3 thread n…JS Engine

event looperevent loop

All of your code runs in this one thread

event queue

Page 50: SWE 432 -Web Application Week 3: Development Asynchronous ...

The Event Loop

21

Event Queue

thread 1 thread 2 thread 3 thread n…JS Engine

event

Page 51: SWE 432 -Web Application Week 3: Development Asynchronous ...

The Event Loop

21

Event Queue

thread 1 thread 2 thread 3 thread n…JS Engine

event

response from google.com

Pushes new event into queue

Page 52: SWE 432 -Web Application Week 3: Development Asynchronous ...

The Event Loop

21

Event Queue

thread 1 thread 2 thread 3 thread n…JS Engine

event

response from google.com

response from facebook.com

Pushes new event into

Page 53: SWE 432 -Web Application Week 3: Development Asynchronous ...

The Event Loop

21

Event Queue

thread 1 thread 2 thread 3 thread n…JS Engine

event

response from google.com

response from facebook.com

response from gmu.edu

Pushes new event into queue

Page 54: SWE 432 -Web Application Week 3: Development Asynchronous ...

The Event Loop

21

Event Queue

thread 1 thread 2 thread 3 thread n…JS Engine

event

response from google.com

response from facebook.com

response from gmu.edu

Page 55: SWE 432 -Web Application Week 3: Development Asynchronous ...

Event Being Processed:

The Event Loop

21

Event Queue

thread 1 thread 2 thread 3 thread n…JS Engine

event

response from google.com

response from facebook.com

response from gmu.edu

Page 56: SWE 432 -Web Application Week 3: Development Asynchronous ...

The Event Loop

22

Event Queue

thread 1 thread 2 thread 3 thread n…JS Engine

event

response from google.com

response from facebook.com

response from gmu.edu

Page 57: SWE 432 -Web Application Week 3: Development Asynchronous ...

The Event Loop

22

Event Queue

thread 1 thread 2 thread 3 thread n…JS Engine

event

response from google.com

response from facebook.com

response from gmu.edu

Event Being Processed:

Page 58: SWE 432 -Web Application Week 3: Development Asynchronous ...

The Event Loop

22

Event Queue

thread 1 thread 2 thread 3 thread n…JS Engine

event

response from google.com

response from facebook.com

response from gmu.edu

Event Being Processed:

Are there any listeners registered for this event?

Page 59: SWE 432 -Web Application Week 3: Development Asynchronous ...

The Event Loop

22

Event Queue

thread 1 thread 2 thread 3 thread n…JS Engine

event

response from google.com

response from facebook.com

response from gmu.edu

Event Being Processed:

Are there any listeners registered for this event?

If so, call listener with event

Page 60: SWE 432 -Web Application Week 3: Development Asynchronous ...

The Event Loop

22

Event Queue

thread 1 thread 2 thread 3 thread n…JS Engine

event

response from google.com

response from facebook.com

response from gmu.edu

Event Being Processed:

Are there any listeners registered for this event?

If so, call listener with event

After the listener is finished, repeat

Page 61: SWE 432 -Web Application Week 3: Development Asynchronous ...

The Event Loop

23

Event Queue

thread 1 thread 2 thread 3 thread n…JS Engine

event

response from facebook.com

response from gmu.edu

Page 62: SWE 432 -Web Application Week 3: Development Asynchronous ...

The Event Loop

23

Event Queue

thread 1 thread 2 thread 3 thread n…JS Engine

event

response from facebook.com

response from gmu.edu

Event Being Processed:

Page 63: SWE 432 -Web Application Week 3: Development Asynchronous ...

The Event Loop

23

Event Queue

thread 1 thread 2 thread 3 thread n…JS Engine

event

response from facebook.com

response from gmu.edu

Event Being Processed:

Are there any listeners registered for this event?

Page 64: SWE 432 -Web Application Week 3: Development Asynchronous ...

The Event Loop

23

Event Queue

thread 1 thread 2 thread 3 thread n…JS Engine

event

response from facebook.com

response from gmu.edu

Event Being Processed:

Are there any listeners registered for this event?

If so, call listener with event

Page 65: SWE 432 -Web Application Week 3: Development Asynchronous ...

The Event Loop

23

Event Queue

thread 1 thread 2 thread 3 thread n…JS Engine

event

response from facebook.com

response from gmu.edu

Event Being Processed:

Are there any listeners registered for this event?

If so, call listener with event

After the listener is finished, repeat

Page 66: SWE 432 -Web Application Week 3: Development Asynchronous ...

The Event Loop

24

Event Queue

thread 1 thread 2 thread 3 thread n…JS Engine

event

response from gmu.edu

Page 67: SWE 432 -Web Application Week 3: Development Asynchronous ...

The Event Loop

24

Event Queue

thread 1 thread 2 thread 3 thread n…JS Engine

event

response from gmu.edu

Event Being Processed:

Page 68: SWE 432 -Web Application Week 3: Development Asynchronous ...

The Event Loop

24

Event Queue

thread 1 thread 2 thread 3 thread n…JS Engine

event

Are there any listeners registered for this event?

response from gmu.edu

Event Being Processed:

Page 69: SWE 432 -Web Application Week 3: Development Asynchronous ...

The Event Loop

24

Event Queue

thread 1 thread 2 thread 3 thread n…JS Engine

event

Are there any listeners registered for this event?

If so, call listener with event

response from gmu.edu

Event Being Processed:

Page 70: SWE 432 -Web Application Week 3: Development Asynchronous ...

The Event Loop

24

Event Queue

thread 1 thread 2 thread 3 thread n…JS Engine

event

Are there any listeners registered for this event?

If so, call listener with event

After the listener is finished, repeat

response from gmu.edu

Event Being Processed:

Page 71: SWE 432 -Web Application Week 3: Development Asynchronous ...

The Event Loop

25

• Remember that JS is event-driven var request = require('request'); request('http://www.google.com', function (error, response, body) { console.log("Heard back from Google!"); }); console.log("Made request");

• Event loop is responsible for dispatching events when they occur

• Main thread for event loop: while(queue.waitForMessage()){queue.processNextMessage();}

Page 72: SWE 432 -Web Application Week 3: Development Asynchronous ...

How do you write a “good” event handler?

• Run-to-completion

• The JS engine will not handle the next event until your event handler finishes

• Good news: no other code will run until you finish (no worries about other threads overwriting your data)

• Bad/OK news: Event handlers must not block

• Blocking -> Stall/wait for input (e.g. alert(), non-async network requests)

• If you *must* do something that takes a long time (e.g. computation), split it up into multiple events

26

Page 73: SWE 432 -Web Application Week 3: Development Asynchronous ...

More Properties of Good Handlers

• Remember that event events are processed in the order they are received

• Events might arrive in unexpected order

• Handlers should check the current state of the app to see if they are still relevant

27

Page 74: SWE 432 -Web Application Week 3: Development Asynchronous ...

Prioritizing Events in node.js

• Some events are more important than others

• Keep separate queues for each event "phase"

• Process all events in each phase before moving to next

28

https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/

First

Last

Page 75: SWE 432 -Web Application Week 3: Development Asynchronous ...

Benefits vs. Explicit Threading (Java)

• Writing your own threads is difficult to reason about and get right:

• When threads share data, need to ensure they correctly synchronize on it to avoid race conditions

• Main downside to events:

• Can not have slow event handlers

• Can still have races, although easier to reason about

29

Page 76: SWE 432 -Web Application Week 3: Development Asynchronous ...

Run-to-Completion Semantics

• Run-to-completion

• The function handling an event and the functions that it (transitively) synchronously calls will keep executing until the function finishes.

• The JS engine will not handle the next event until the event handler finishes.

30

callback1f

h

g

callback2

... i

j...

processing of event queue

Page 77: SWE 432 -Web Application Week 3: Development Asynchronous ...

Implications of Run-to-Completion

• Good news: no other code will run until you finish (no worries about other threads overwriting your data)

31

callback1f

h

g

callback2

... i

j...

processing of event queue

j will not execute until after i

Page 78: SWE 432 -Web Application Week 3: Development Asynchronous ...

Implications of Run-to-Completion

• Bad/OK news: Nothing else will happen until event handler returns

• Event handlers should never block (e.g., wait for input) --> all callbacks waiting for network response or user input are always asynchronous

• Event handlers shouldn't take a long time either

32

callback1f

h

g

callback2

... i

j...

processing of event queue

jwill not execute until i finishes

Page 79: SWE 432 -Web Application Week 3: Development Asynchronous ...

Decomposing a long-running computation

• If you must do something that takes a long time (e.g. computation), split it into multiple events

• doSomeWork();

• ... [let event loop process other events]..

• continueDoingMoreWork();

• ...

33

Page 80: SWE 432 -Web Application Week 3: Development Asynchronous ...

Dangers of Decomposition

• Application state may change before event occurs

• Other event handlers may be interleaved and occur before event occurs and mutate the same application state

• --> Need to check that update still makes sense

• Application state may be in inconsistent state until event occurs

• leaving data in inconsistent state...

• Loading some data from API, but not all of it...

34

Page 81: SWE 432 -Web Application Week 3: Development Asynchronous ...

Sequencing events

• We'd like a better way to sequence events.

• Goals:

• Clearly distinguish synchronous from asynchronous function calls.

• Enable computation to occur only after some event has happened, without adding an additional nesting level each time (no pyramid of doom).

• Make it possible to handle errors, including for multiple related async requests.

• Make it possible to wait for multiple async calls to finish before proceeding.

35

Page 82: SWE 432 -Web Application Week 3: Development Asynchronous ...

Sequencing events with Promises

• Promises are a wrapper around async callbacks

• Promises represents how to get a value

• Then you tell the promise what to do when it gets it

• Promises organize many steps that need to happen in order, with each step happening asynchronously

• At any point a promise is either:

• Unresolved

• Succeeds

• Fails

36

Page 83: SWE 432 -Web Application Week 3: Development Asynchronous ...

Using a Promise

• Declare what you want to do when your promise is completed (then), or if there’s an error (catch)

37

fetch('https://github.com/') .then(function(res) { return res.text(); });

fetch('http://domain.invalid/') .catch(function(err) { console.log(err); });

Page 84: SWE 432 -Web Application Week 3: Development Asynchronous ...

Promise One Thing Then Another

38

Promise to get some data

Page 85: SWE 432 -Web Application Week 3: Development Asynchronous ...

Promise One Thing Then Another

38

Promise to get some data

Promise to get some data based on that

data

then

Page 86: SWE 432 -Web Application Week 3: Development Asynchronous ...

Promise One Thing Then Another

38

Promise to get some data

Promise to get some data based on that

data

then

then

Use that data to update application

state

Page 87: SWE 432 -Web Application Week 3: Development Asynchronous ...

Promise One Thing Then Another

38

Promise to get some data

Promise to get some data based on that

data

then

then

Use that data to update application

state

Report on the error

If there’s an error…

If there’s an error…

Page 88: SWE 432 -Web Application Week 3: Development Asynchronous ...

Chaining Promises

39

Page 89: SWE 432 -Web Application Week 3: Development Asynchronous ...

Chaining Promises

39

myPromise.then(function(resultOfPromise){ //Do something, maybe asynchronously return theResultOfThisStep; })

Page 90: SWE 432 -Web Application Week 3: Development Asynchronous ...

Chaining Promises

39

myPromise.then(function(resultOfPromise){ //Do something, maybe asynchronously return theResultOfThisStep; }).then(function(resultOfStep1){ //Do something, maybe asynchronously return theResultOfStep2; })

Page 91: SWE 432 -Web Application Week 3: Development Asynchronous ...

Chaining Promises

39

myPromise.then(function(resultOfPromise){ //Do something, maybe asynchronously return theResultOfThisStep; }).then(function(resultOfStep1){ //Do something, maybe asynchronously return theResultOfStep2; }).then(function(resultOfStep2){ //Do something, maybe asynchronously return theResultOfStep3; })

Page 92: SWE 432 -Web Application Week 3: Development Asynchronous ...

Chaining Promises

39

myPromise.then(function(resultOfPromise){ //Do something, maybe asynchronously return theResultOfThisStep; }).then(function(resultOfStep1){ //Do something, maybe asynchronously return theResultOfStep2; }).then(function(resultOfStep2){ //Do something, maybe asynchronously return theResultOfStep3; }).then(function(resultOfStep3){ //Do something, maybe asynchronously return theResultOfStep4; })

Page 93: SWE 432 -Web Application Week 3: Development Asynchronous ...

Chaining Promises

39

myPromise.then(function(resultOfPromise){ //Do something, maybe asynchronously return theResultOfThisStep; }).then(function(resultOfStep1){ //Do something, maybe asynchronously return theResultOfStep2; }).then(function(resultOfStep2){ //Do something, maybe asynchronously return theResultOfStep3; }).then(function(resultOfStep3){ //Do something, maybe asynchronously return theResultOfStep4; }).catch(function(error){ });

Page 94: SWE 432 -Web Application Week 3: Development Asynchronous ...

Writing a Promise

• Most often, Promises will be generated by an API function (e.g., fetch) and returned to you.

• But you can also create your own Promise.

40

var p = new Promise(function(resolve, reject) { if (/* condition */) { resolve(/* value */); // fulfilled successfully } else { reject(/* reason */); // error, rejected } });

Page 95: SWE 432 -Web Application Week 3: Development Asynchronous ...

Example: Writing a Promise

• loadImage returns a promise to load a given image

function loadImage(url){ return new Promise(function(resolve, reject) { var img = new Image(); img.src = url; img.onload = function(){ resolve(img); } img.onerror = function(e){ reject(e); } }); }

41

Once the image is loaded, we’ll resolve the promise

If the image has an error, the promise is rejected

Page 96: SWE 432 -Web Application Week 3: Development Asynchronous ...

Writing a Promise

• Basic syntax:

• do something (possibly asynchronous)

• when you get the result, call resolve() and pass the final result

• In case of error, call reject()

42

var p = new Promise( function(resolve,reject){ // do something, who knows how long it will take? if(everythingIsOK) { resolve(stateIWantToSave); } else reject(Error("Some error happened")); } );

Page 97: SWE 432 -Web Application Week 3: Development Asynchronous ...

Promises in Action

43

Page 98: SWE 432 -Web Application Week 3: Development Asynchronous ...

Promises in Action

• Firebase example: get some value from the database, then push some new value to the database, then print out “OK”

43

Page 99: SWE 432 -Web Application Week 3: Development Asynchronous ...

Promises in Action

• Firebase example: get some value from the database, then push some new value to the database, then print out “OK”

43

Page 100: SWE 432 -Web Application Week 3: Development Asynchronous ...

Promises in Action

• Firebase example: get some value from the database, then push some new value to the database, then print out “OK”

43

Page 101: SWE 432 -Web Application Week 3: Development Asynchronous ...

Promises in Action

• Firebase example: get some value from the database, then push some new value to the database, then print out “OK”

todosRef.child(keyToGet).once(‘value') .then(function(foundTodo){ return foundTodo.val().text; }) .then(function(theText){ todosRef.push({'text' : "Seriously: " + theText}); }) .then(function(){ console.log("OK!"); }) .catch(function(error){ //something went wrong });

43

Page 102: SWE 432 -Web Application Week 3: Development Asynchronous ...

Promises in Action

• Firebase example: get some value from the database, then push some new value to the database, then print out “OK”

todosRef.child(keyToGet).once(‘value') .then(function(foundTodo){ return foundTodo.val().text; }) .then(function(theText){ todosRef.push({'text' : "Seriously: " + theText}); }) .then(function(){ console.log("OK!"); }) .catch(function(error){ //something went wrong });

43

Do this

Page 103: SWE 432 -Web Application Week 3: Development Asynchronous ...

Promises in Action

• Firebase example: get some value from the database, then push some new value to the database, then print out “OK”

todosRef.child(keyToGet).once(‘value') .then(function(foundTodo){ return foundTodo.val().text; }) .then(function(theText){ todosRef.push({'text' : "Seriously: " + theText}); }) .then(function(){ console.log("OK!"); }) .catch(function(error){ //something went wrong });

43

Do thisThen, do this

Page 104: SWE 432 -Web Application Week 3: Development Asynchronous ...

Promises in Action

• Firebase example: get some value from the database, then push some new value to the database, then print out “OK”

todosRef.child(keyToGet).once(‘value') .then(function(foundTodo){ return foundTodo.val().text; }) .then(function(theText){ todosRef.push({'text' : "Seriously: " + theText}); }) .then(function(){ console.log("OK!"); }) .catch(function(error){ //something went wrong });

43

Do thisThen, do this

Then do this

Page 105: SWE 432 -Web Application Week 3: Development Asynchronous ...

Promises in Action

• Firebase example: get some value from the database, then push some new value to the database, then print out “OK”

todosRef.child(keyToGet).once(‘value') .then(function(foundTodo){ return foundTodo.val().text; }) .then(function(theText){ todosRef.push({'text' : "Seriously: " + theText}); }) .then(function(){ console.log("OK!"); }) .catch(function(error){ //something went wrong });

43

Do thisThen, do this

Then do this

And if you ever had an error, do this

Page 106: SWE 432 -Web Application Week 3: Development Asynchronous ...

Testing Promises

44https://jestjs.io/docs/en/tutorial-async

function getUserName(userID) { return request-promise(‘/users/‘ + userID).then(user => user.name); }

Page 107: SWE 432 -Web Application Week 3: Development Asynchronous ...

Testing Promises

44https://jestjs.io/docs/en/tutorial-async

function getUserName(userID) { return request-promise(‘/users/‘ + userID).then(user => user.name); }

it('works with promises', () => { expect(user.getUserName(4).toEqual(‘Mark’)); });

Page 108: SWE 432 -Web Application Week 3: Development Asynchronous ...

Testing Promises

44https://jestjs.io/docs/en/tutorial-async

function getUserName(userID) { return request-promise(‘/users/‘ + userID).then(user => user.name); }

it('works with promises', () => { expect.assertions(1); return user.getUserName(4).then(data => expect(data).toEqual('Mark')); });

it('works with promises', () => { expect(user.getUserName(4).toEqual(‘Mark’)); });

Page 109: SWE 432 -Web Application Week 3: Development Asynchronous ...

Testing Promises

44https://jestjs.io/docs/en/tutorial-async

function getUserName(userID) { return request-promise(‘/users/‘ + userID).then(user => user.name); }

it('works with promises', () => { expect.assertions(1); return user.getUserName(4).then(data => expect(data).toEqual('Mark')); });

it('works with resolves', () => { expect.assertions(1); return expect(user.getUserName(5)).resolves.toEqual('Paul'); });

it('works with promises', () => { expect(user.getUserName(4).toEqual(‘Mark’)); });

Page 110: SWE 432 -Web Application Week 3: Development Asynchronous ...

Testing Promises

44https://jestjs.io/docs/en/tutorial-async

function getUserName(userID) { return request-promise(‘/users/‘ + userID).then(user => user.name); }

it('works with promises', () => { expect.assertions(1); return user.getUserName(4).then(data => expect(data).toEqual('Mark')); });

it('works with resolves', () => { expect.assertions(1); return expect(user.getUserName(5)).resolves.toEqual('Paul'); });

it('works with promises', () => { expect(user.getUserName(4).toEqual(‘Mark’)); });

Page 111: SWE 432 -Web Application Week 3: Development Asynchronous ...

45

SWE 432 - Web Application

Development

Page 112: SWE 432 -Web Application Week 3: Development Asynchronous ...

45

SWE 432 - Web Application

Development

Page 113: SWE 432 -Web Application Week 3: Development Asynchronous ...

Asynchronous Programming II

46

Page 114: SWE 432 -Web Application Week 3: Development Asynchronous ...

Review: Asynchronous

• Synchronous:

• Make a function call

• When function call returns, the work is done

• Asynchronous:

• Make a function call

• Function returns immediately, before completing work!

47

Page 115: SWE 432 -Web Application Week 3: Development Asynchronous ...

Review: Asynchronous

• How we do multiple things at a time in JS

• NodeJS magically handles these asynchronous things in the background

• Really important when doing file/network input/output

48

Page 116: SWE 432 -Web Application Week 3: Development Asynchronous ...

Review: Run-to-completion semantics

• Run-to-completion

• The function handling an event and the functions that it (transitively) synchronously calls will keep executing until the function finishes.

• The JS engine will not handle the next event until the event handler finishes.

49

callback1f

h

g

callback2

... i

j...

processing of event queue

Page 117: SWE 432 -Web Application Week 3: Development Asynchronous ...

Review: Implications of run-to-completion

• Good news: no other code will run until you finish (no worries about other threads overwriting your data)

50

callback1f

h

g

callback2

... i

j...

processing of event queue

j will not execute until after i

Page 118: SWE 432 -Web Application Week 3: Development Asynchronous ...

Review: Implications of run-to-completion

• Bad/OK news: Nothing else will happen until event handler returns

• Event handlers should never block (e.g., wait for input) --> all callbacks waiting for network response or user input are always asynchronous

• Event handlers shouldn't take a long time either

51

callback1f

h

g

callback2

... i

j...

processing of event queue

jwill not execute until i finishes

Page 119: SWE 432 -Web Application Week 3: Development Asynchronous ...

Review: Chaining Promises

52

Page 120: SWE 432 -Web Application Week 3: Development Asynchronous ...

Review: Chaining Promises

52

myPromise.then(function(resultOfPromise){ //Do something, maybe asynchronously return theResultOfThisStep; })

Page 121: SWE 432 -Web Application Week 3: Development Asynchronous ...

Review: Chaining Promises

52

myPromise.then(function(resultOfPromise){ //Do something, maybe asynchronously return theResultOfThisStep; }).then(function(resultOfStep1){ //Do something, maybe asynchronously return theResultOfStep2; })

Page 122: SWE 432 -Web Application Week 3: Development Asynchronous ...

Review: Chaining Promises

52

myPromise.then(function(resultOfPromise){ //Do something, maybe asynchronously return theResultOfThisStep; }).then(function(resultOfStep1){ //Do something, maybe asynchronously return theResultOfStep2; }).then(function(resultOfStep2){ //Do something, maybe asynchronously return theResultOfStep3; })

Page 123: SWE 432 -Web Application Week 3: Development Asynchronous ...

Review: Chaining Promises

52

myPromise.then(function(resultOfPromise){ //Do something, maybe asynchronously return theResultOfThisStep; }).then(function(resultOfStep1){ //Do something, maybe asynchronously return theResultOfStep2; }).then(function(resultOfStep2){ //Do something, maybe asynchronously return theResultOfStep3; }).then(function(resultOfStep3){ //Do something, maybe asynchronously return theResultOfStep4; })

Page 124: SWE 432 -Web Application Week 3: Development Asynchronous ...

Review: Chaining Promises

52

myPromise.then(function(resultOfPromise){ //Do something, maybe asynchronously return theResultOfThisStep; }).then(function(resultOfStep1){ //Do something, maybe asynchronously return theResultOfStep2; }).then(function(resultOfStep2){ //Do something, maybe asynchronously return theResultOfStep3; }).then(function(resultOfStep3){ //Do something, maybe asynchronously return theResultOfStep4; }).catch(function(error){ });

Page 125: SWE 432 -Web Application Week 3: Development Asynchronous ...

Current Lecture

• Async/await

• Programming activity

53

Page 126: SWE 432 -Web Application Week 3: Development Asynchronous ...

Promising many things

• Can also specify that *many* things should be done, and then something else

• Example: load a whole bunch of images at once: Promise .all([loadImage("GMURGB.jpg"), loadImage(“CS.jpg")]) .then(function (imgArray) { imgArray.forEach(img => {document.body.appendChild(img)}) }) .catch(function (e) { console.log("Oops"); console.log(e); });

54

Page 127: SWE 432 -Web Application Week 3: Development Asynchronous ...

Async Programming Example

55

Go get a data item

thenCombine

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Group all Cal updates

Group all news updates

when done

Update display

Explain example

1 se

cond

eac

h2

seco

nds

each

Page 128: SWE 432 -Web Application Week 3: Development Asynchronous ...

Synchronous Version

56

Page 129: SWE 432 -Web Application Week 3: Development Asynchronous ...

Synchronous Version

56

Go get a data item

Page 130: SWE 432 -Web Application Week 3: Development Asynchronous ...

Synchronous Version

56

Go get a data item

Go get a data item

Page 131: SWE 432 -Web Application Week 3: Development Asynchronous ...

Synchronous Version

56

Go get a data item

Go get a data item

Go get a data item

Page 132: SWE 432 -Web Application Week 3: Development Asynchronous ...

Synchronous Version

56

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Page 133: SWE 432 -Web Application Week 3: Development Asynchronous ...

Synchronous Version

56

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Page 134: SWE 432 -Web Application Week 3: Development Asynchronous ...

Synchronous Version

56

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Page 135: SWE 432 -Web Application Week 3: Development Asynchronous ...

Synchronous Version

56

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Page 136: SWE 432 -Web Application Week 3: Development Asynchronous ...

Synchronous Version

56

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Page 137: SWE 432 -Web Application Week 3: Development Asynchronous ...

Synchronous Version

56

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Page 138: SWE 432 -Web Application Week 3: Development Asynchronous ...

Synchronous Version

56

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Page 139: SWE 432 -Web Application Week 3: Development Asynchronous ...

Synchronous Version

56

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Group all Cal updates

Page 140: SWE 432 -Web Application Week 3: Development Asynchronous ...

Synchronous Version

56

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Group all Cal updates

Group all news updates

Page 141: SWE 432 -Web Application Week 3: Development Asynchronous ...

Synchronous Version

56

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Group all Cal updates

Group all news updates

Update the display

Page 142: SWE 432 -Web Application Week 3: Development Asynchronous ...

Synchronous Version

56

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Group all Cal updates

Group all news updates

Update the display

Explain example

Page 143: SWE 432 -Web Application Week 3: Development Asynchronous ...

Asynchronous Version

57

Page 144: SWE 432 -Web Application Week 3: Development Asynchronous ...

Asynchronous Version

57

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Explain example

Page 145: SWE 432 -Web Application Week 3: Development Asynchronous ...

Asynchronous Version

57

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Explain example

Group all Cal updates

Group all news updates

Page 146: SWE 432 -Web Application Week 3: Development Asynchronous ...

Asynchronous Version

57

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Go get a data item

Explain example

Group all Cal updates

Group all news updates

Update the display

Page 147: SWE 432 -Web Application Week 3: Development Asynchronous ...

Async Programming Example (Sync)

58

let lib = require("./lib.js"); let thingsToFetch = [‘t1','t2','t3','s1','s2', 's3','m1','m2','m3','t4']; let stuff = []; for(let thingToGet of thingsToFetch) { stuff.push(lib.getSync(thingToGet)); console.log("Got a thing"); } //Got all my stuff let ts = lib.groupSync(stuff,"t"); console.log("Grouped"); let ms = lib.groupSync(stuff,"m"); console.log("Grouped"); let ss = lib.groupSync(stuff,"s"); console.log("Grouped");

console.log("Done");

Page 148: SWE 432 -Web Application Week 3: Development Asynchronous ...

Async Programming Example (Sync)

58

let lib = require("./lib.js"); let thingsToFetch = [‘t1','t2','t3','s1','s2', 's3','m1','m2','m3','t4']; let stuff = []; for(let thingToGet of thingsToFetch) { stuff.push(lib.getSync(thingToGet)); console.log("Got a thing"); } //Got all my stuff let ts = lib.groupSync(stuff,"t"); console.log("Grouped"); let ms = lib.groupSync(stuff,"m"); console.log("Grouped"); let ss = lib.groupSync(stuff,"s"); console.log("Grouped");

console.log("Done");

Page 149: SWE 432 -Web Application Week 3: Development Asynchronous ...

Async Programming Example (Callbacks, no parallelism)

59

let lib = require("./lib.js");

let thingsToFetch = ['t1', 't2', 't3', 's1', 's2', 's3', 'm1', 'm2', 'm3', 't4']; let stuff = []; let ts, ms, ss; let outstandingStuffToGet = thingsToFetch.length;

lib.getASync(thingsToFetch[0],(v)=>{ stuff.push(v); console.log("Got a thing") lib.getASync(thingsToFetch[1],(v)=>{ stuff.push(v); console.log("Got a thing") lib.getASync(thingsToFetch[2],(v)=>{ stuff.push(v); console.log("Got a thing") lib.getASync(thingsToFetch[3],(v)=>{ stuff.push(v); console.log("Got a thing") lib.getASync(thingsToFetch[4],(v)=>{ stuff.push(v); console.log("Got a thing") lib.getASync(thingsToFetch[5],(v)=>{ stuff.push(v); console.log("Got a thing") lib.getASync(thingsToFetch[6],(v)=>{ stuff.push(v); console.log("Got a thing") lib.getASync(thingsToFetch[7],(v)=>{ stuff.push(v); console.log("Got a thing") lib.getASync(thingsToFetch[8],(v)=>{ stuff.push(v); console.log("Got a thing") lib.getASync(thingsToFetch[9],(v)=>{ stuff.push(v); console.log("Got a thing") lib.groupAsync(stuff, "t", (t) => { ts = t; console.log("Grouped"); lib.groupAsync(stuff, "m", (m) => { ss = s; console.log("Grouped"); lib.groupAsync(stuff, "s", (s) => {

Page 150: SWE 432 -Web Application Week 3: Development Asynchronous ...

Async Programming Example (Callbacks, no parallelism)

59

let lib = require("./lib.js");

let thingsToFetch = ['t1', 't2', 't3', 's1', 's2', 's3', 'm1', 'm2', 'm3', 't4']; let stuff = []; let ts, ms, ss; let outstandingStuffToGet = thingsToFetch.length;

lib.getASync(thingsToFetch[0],(v)=>{ stuff.push(v); console.log("Got a thing") lib.getASync(thingsToFetch[1],(v)=>{ stuff.push(v); console.log("Got a thing") lib.getASync(thingsToFetch[2],(v)=>{ stuff.push(v); console.log("Got a thing") lib.getASync(thingsToFetch[3],(v)=>{ stuff.push(v); console.log("Got a thing") lib.getASync(thingsToFetch[4],(v)=>{ stuff.push(v); console.log("Got a thing") lib.getASync(thingsToFetch[5],(v)=>{ stuff.push(v); console.log("Got a thing") lib.getASync(thingsToFetch[6],(v)=>{ stuff.push(v); console.log("Got a thing") lib.getASync(thingsToFetch[7],(v)=>{ stuff.push(v); console.log("Got a thing") lib.getASync(thingsToFetch[8],(v)=>{ stuff.push(v); console.log("Got a thing") lib.getASync(thingsToFetch[9],(v)=>{ stuff.push(v); console.log("Got a thing") lib.groupAsync(stuff, "t", (t) => { ts = t; console.log("Grouped"); lib.groupAsync(stuff, "m", (m) => { ss = s; console.log("Grouped"); lib.groupAsync(stuff, "s", (s) => {

Page 151: SWE 432 -Web Application Week 3: Development Asynchronous ...

Async Programming Example (Callbacks)

60

let lib = require("./lib.js");

let thingsToFetch = ['t1', 't2', 't3', 's1', 's2', 's3', 'm1', 'm2', 'm3', 't4']; let stuff = []; let ts, ms, ss; let outstandingStuffToGet = thingsToFetch.length; for (let thingToGet of thingsToFetch) { lib.getASync(thingToGet, (v) => { stuff.push(v); console.log("Got a thing") outstandingStuffToGet--; if (outstandingStuffToGet == 0) { let groupsOfStuffTogetStill = 3; lib.groupAsync(stuff, "t", (t) => { ts = t; console.log("Grouped"); groupsOfStuffTogetStill--; if (groupsOfStuffTogetStill == 0) console.log("Done");

}); lib.groupAsync(stuff, "m", (m) => { ms = m; console.log("Grouped"); groupsOfStuffTogetStill--; if (groupsOfStuffTogetStill == 0) console.log("Done"); }); lib.groupAsync(stuff, "s", (s) => { ss = s; console.log("Grouped"); groupsOfStuffTogetStill--; if (groupsOfStuffTogetStill == 0) console.log("Done"); }) } }); }

Page 152: SWE 432 -Web Application Week 3: Development Asynchronous ...

Async Programming Example (Callbacks)

60

let lib = require("./lib.js");

let thingsToFetch = ['t1', 't2', 't3', 's1', 's2', 's3', 'm1', 'm2', 'm3', 't4']; let stuff = []; let ts, ms, ss; let outstandingStuffToGet = thingsToFetch.length; for (let thingToGet of thingsToFetch) { lib.getASync(thingToGet, (v) => { stuff.push(v); console.log("Got a thing") outstandingStuffToGet--; if (outstandingStuffToGet == 0) { let groupsOfStuffTogetStill = 3; lib.groupAsync(stuff, "t", (t) => { ts = t; console.log("Grouped"); groupsOfStuffTogetStill--; if (groupsOfStuffTogetStill == 0) console.log("Done");

}); lib.groupAsync(stuff, "m", (m) => { ms = m; console.log("Grouped"); groupsOfStuffTogetStill--; if (groupsOfStuffTogetStill == 0) console.log("Done"); }); lib.groupAsync(stuff, "s", (s) => { ss = s; console.log("Grouped"); groupsOfStuffTogetStill--; if (groupsOfStuffTogetStill == 0) console.log("Done"); }) } }); }

Page 153: SWE 432 -Web Application Week 3: Development Asynchronous ...

Async Programming Example (Promises, no parallelism)

61

let lib = require("./lib.js");

let thingsToFetch = ['t1', 't2', 't3', 's1', 's2', 's3', 'm1', 'm2', 'm3', 't4']; let stuff = []; let ts, ms, ss; let outstandingStuffToGet = thingsToFetch.length; lib.getPromise(thingsToFetch[0]).then( (v)=>{ stuff.push(v); console.log("Got a thing"); return lib.getPromise(thingsToFetch[1]); } ).then( (v)=>{ stuff.push(v); console.log("Got a thing"); return lib.getPromise(thingsToFetch[1]); } ).then( (v)=>{ stuff.push(v); console.log("Got a thing"); return lib.getPromise(thingsToFetch[1]); } ).then( (v)=>{ stuff.push(v); console.log("Got a thing"); return lib.getPromise(thingsToFetch[2]); } ).then( (v)=>{ stuff.push(v); console.log("Got a thing"); return lib.getPromise(thingsToFetch[3]); } ).then( (v)=>{ stuff.push(v); console.log("Got a thing"); return lib.getPromise(thingsToFetch[4]); }

Page 154: SWE 432 -Web Application Week 3: Development Asynchronous ...

Async Programming Example (Promises, no parallelism)

61

let lib = require("./lib.js");

let thingsToFetch = ['t1', 't2', 't3', 's1', 's2', 's3', 'm1', 'm2', 'm3', 't4']; let stuff = []; let ts, ms, ss; let outstandingStuffToGet = thingsToFetch.length; lib.getPromise(thingsToFetch[0]).then( (v)=>{ stuff.push(v); console.log("Got a thing"); return lib.getPromise(thingsToFetch[1]); } ).then( (v)=>{ stuff.push(v); console.log("Got a thing"); return lib.getPromise(thingsToFetch[1]); } ).then( (v)=>{ stuff.push(v); console.log("Got a thing"); return lib.getPromise(thingsToFetch[1]); } ).then( (v)=>{ stuff.push(v); console.log("Got a thing"); return lib.getPromise(thingsToFetch[2]); } ).then( (v)=>{ stuff.push(v); console.log("Got a thing"); return lib.getPromise(thingsToFetch[3]); } ).then( (v)=>{ stuff.push(v); console.log("Got a thing"); return lib.getPromise(thingsToFetch[4]); }

Page 155: SWE 432 -Web Application Week 3: Development Asynchronous ...

Async Programming Example (Promises)

62

let lib = require("./lib.js");

let thingsToFetch = ['t1', 't2', 't3', 's1', 's2', 's3', ‘m1', 'm2', 'm3', 't4']; let stuff = []; let ts, ms, ss;

let promises = []; for (let thingToGet of thingsToFetch) { promises.push(lib.getPromise(thingToGet)); } Promise.all(promises).then((data) => { console.log("Got all things"); stuff = data; return Promise.all([ lib.groupPromise(stuff, "t"), lib.groupPromise(stuff, "m"), lib.groupPromise(stuff, "s") ] ) }).then((groups) => { console.log("Got all groups"); ts = groups[0]; ms = groups[1]; ss = groups[2]; console.log("Done"); });

Page 156: SWE 432 -Web Application Week 3: Development Asynchronous ...

Async Programming Example (Promises)

62

let lib = require("./lib.js");

let thingsToFetch = ['t1', 't2', 't3', 's1', 's2', 's3', ‘m1', 'm2', 'm3', 't4']; let stuff = []; let ts, ms, ss;

let promises = []; for (let thingToGet of thingsToFetch) { promises.push(lib.getPromise(thingToGet)); } Promise.all(promises).then((data) => { console.log("Got all things"); stuff = data; return Promise.all([ lib.groupPromise(stuff, "t"), lib.groupPromise(stuff, "m"), lib.groupPromise(stuff, "s") ] ) }).then((groups) => { console.log("Got all groups"); ts = groups[0]; ms = groups[1]; ss = groups[2]; console.log("Done"); });

Page 157: SWE 432 -Web Application Week 3: Development Asynchronous ...

Problems with Promises

63

const makeRequest = () => { try { return promise1() .then(value1 => { // do something }).catch(err => { //This is the only way to catch async errors console.log(err); }) }catch(ex){ //Will never catch async errors!! } }

Page 158: SWE 432 -Web Application Week 3: Development Asynchronous ...

Async/Await

• The latest and greatest way to work with async functions

• A programming pattern that tries to make async code look more synchronous

• Just “await” something to happen before proceeding

• https://javascript.info/async-await

64

Page 159: SWE 432 -Web Application Week 3: Development Asynchronous ...

Async keyword

• Denotes a function that can block and resume execution later

• Automatically turns the return type into a Promise

65

async function hello() { return "Hello" }; hello();

Page 160: SWE 432 -Web Application Week 3: Development Asynchronous ...

Async/Await Example

66

function resolveAfter2Seconds() { return new Promise(resolve => { setTimeout(() => { resolve('resolved'); }, 2000); }); }

async function asyncCall() { console.log('calling'); var result = await resolveAfter2Seconds(); console.log(result); // expected output: 'resolved' }

https://replit.com/@kmoran/async-ex#script.js

Page 161: SWE 432 -Web Application Week 3: Development Asynchronous ...

Async/Await Example

66

function resolveAfter2Seconds() { return new Promise(resolve => { setTimeout(() => { resolve('resolved'); }, 2000); }); }

async function asyncCall() { console.log('calling'); var result = await resolveAfter2Seconds(); console.log(result); // expected output: 'resolved' }

https://replit.com/@kmoran/async-ex#script.js

Page 162: SWE 432 -Web Application Week 3: Development Asynchronous ...

Async/Await -> Synchronous

67

let lib = require("./lib.js");

async function getAndGroupStuff() { let thingsToFetch = ['t1', 't2', 't3', 's1', 's2', ‘s3’, 'm1', 'm2', 'm3', 't4']; let stuff = []; let ts, ms, ss;

let promises = []; for (let thingToGet of thingsToFetch) { stuff.push(await lib.getPromise(thingToGet)); console.log("Got a thing"); } ts = await lib.groupPromise(stuff,"t"); console.log("Made a group"); ms = await lib.groupPromise(stuff,"m"); console.log("Made a group"); ss = await lib.groupPromise(stuff,"s"); console.log("Made a group"); console.log("Done"); }

getAndGroupStuff();

Page 163: SWE 432 -Web Application Week 3: Development Asynchronous ...

Async/Await -> Synchronous

67

let lib = require("./lib.js");

async function getAndGroupStuff() { let thingsToFetch = ['t1', 't2', 't3', 's1', 's2', ‘s3’, 'm1', 'm2', 'm3', 't4']; let stuff = []; let ts, ms, ss;

let promises = []; for (let thingToGet of thingsToFetch) { stuff.push(await lib.getPromise(thingToGet)); console.log("Got a thing"); } ts = await lib.groupPromise(stuff,"t"); console.log("Made a group"); ms = await lib.groupPromise(stuff,"m"); console.log("Made a group"); ss = await lib.groupPromise(stuff,"s"); console.log("Made a group"); console.log("Done"); }

getAndGroupStuff();

Page 164: SWE 432 -Web Application Week 3: Development Asynchronous ...

Async/Await

• Rules of the road:

• You can only call await from a function that is async

• You can only await on functions that return a Promise

• Beware: await makes your code synchronous!

68

async function getAndGroupStuff() { ... ts = await lib.groupPromise(stuff,"t"); ... }

Page 165: SWE 432 -Web Application Week 3: Development Asynchronous ...

Async/Await Activity

69

let lib = require("./lib.js");

async function getAndGroupStuff() { let thingsToFetch = ['t1', 't2', 't3', 's1', 's2', 's3', 'm1', 'm2', 'm3', 't4']; let stuff = []; let ts, ms, ss;

let promises = []; for (let thingToGet of thingsToFetch) { stuff.push(await lib.getPromise(thingToGet)); console.log("Got a thing"); } ts = await lib.groupPromise(stuff,"t"); console.log("Made a group"); ms = await lib.groupPromise(stuff,"m"); console.log("Made a group"); ss = await lib.groupPromise(stuff,"s"); console.log("Made a group"); console.log("Done"); }

getAndGroupStuff();

Rewrite this code so that all of the things are fetched (in parallel) and then all of the groups are collected using async/await

https://replit.com/@kmoran/SWE-Week-3-Activity#index.js

I will also post to Ed right now!

Page 166: SWE 432 -Web Application Week 3: Development Asynchronous ...

Acknowledgements

70

Slides adapted from Dr. Thomas LaToza’s SWE 632 course