Async+Programming
Async+Programming
Asynchronous Programming
1
Patrick Hill
Adjunct Professor
Computer Science Department
Patrick.Hill@stevens.edu
What is Asynchronous Code?
3
Thread Blocking
Blocking thread-based architecture (how apache/PHP run)
4
How JavaScript Is Run
5
How JavaScript Is Run
JavaScript event loop:
6
What Is Synchronous Code?
Synchronous code is code that runs in the order it is written. This is what we are used to
as programmers: we write what happens and it gets done in the order expected.
The key to remembering the difference between asynchronous and synchronous
programming is to view all programming as a chain of operations.
In synchronous code, these operations are run sequentially. Operations that are
written first, will be run first. This will hold true even for functions that run callbacks
despite being synchronous, such as [].map
In asynchronous code, some operations are run non-sequentially. Operations that
are written first may run before other operations, but operations that passed as
parameters to asynchronous functions can get run at any time in the future. No order is
guaranteed.
7
8
What Is Asynchronous Code?
Asynchronous code is code that is not run in the order that which it is written.
Traditionally, asynchronous functions will take callback functions in order to run code
that relies on the result of the function.
Nowadays, this pattern is abstracted away and many asynchronous functions return
promises.
Note: if you have multiple asynchronous functions, there is no guarantee that the first
function that is started will finish before the following asynchronous actions. You must
therefore often start the second asynchronous actions after the first is completed.
9
10
Where Will We Use Asynchronous Code?
11
When Working With Files
There are many file system functions that are exposed through node’s native fs module.
Most of these are asynchronous, as I/O operations on a computer are notoriously slow.
You can do many things such as
• Read and write files
• Get directory listings
• Create and delete directories
• Watch for file changes to occur!
• And more…
• You can read about the fs module at
• https://nodejs.org/api/fs.html
12
Running a Web Server
When you run your own web server, you have no idea when someone will actually access
your routes (if they will at all!).
For this reason, all your server code will be asynchronous. Your server code will have to
wait for a network request to initiate before sending data back down to the client.
13
Making an HTTP Request
Making an HTTP request is an asynchronous operation, since it can take a very long
time for the request to complete.
There are many more parts than you would expect to making an HTTP request, and the
responding server (if it exists) could take any amount of time to complete the request.
For this reason, HTTP requests are asynchronous so that the file can be downloaded and
such while other operations are completing, rather than blocking and holding up your
entire application when a server is responding slowly.
14
Database Operations
15
Callback Functions
16
What Is a Callback Function?
In JavaScript, you can pass functions as the arguments to other functions.
This is very useful for asynchronous code, as you can pass a callback function to a long-
running function. That way, the result will be passed to the callback once the long-
running process is complete. Since the long running function will yield its time to run
many times over (since it is asynchronous), we are not able to simply place code after
our asynchronous function and assume that it will run in the order we write it.
For example:
• You can make a database call that runs asynchronously, and when the result
comes back pass the result to the callback
• You can make a network request that runs asynchronously, and when the request
is completed the response is passed to the callback
17
What Is a Callback Function?
doHomework('math', () => {
console.log('Finished my homework');
});
18
What Is a Callback Function?
19
Things to Note
Callbacks are the most basic and simplest form of managing asynchronous operations in
JavaScript, but come with a number of difficulties.
• Code becomes unreadable; you end up with code that goes deep and ends in the
middle of your file, rather than code that runs as we’re used to (top to bottom).
• Handling errors becomes intensely confusing, as you have to check for them at the
start of every callback.
• Callback Hell
20
Callback Hell
21
Example 1: Reading Files With Callbacks
22
Our Goal
We are going to look at a node script that will perform the following chain of events:
1. It will use prompt to ask the user for the name of a file to open.
2. Once that is complete, it will read the file.
3. Once that is complete, it will reverse the content of the file.
23
Promises
24
What Is a Promise?
Promises are used to handle asynchronous operations in JavaScript. They are easy to
manage when dealing with multiple asynchronous operations where callbacks can create
callback hell leading to unmanageable code.
Prior to promises events and callback functions were used but they had limited
functionalities and created unmanageable code.
Multiple callback functions would create callback hell that leads to unmanageable code.
Events were not good at handling asynchronous operations.
Promises are the ideal choice for handling asynchronous operations in the simplest
manner. They can handle multiple asynchronous operations easily and provide better
error handling than callbacks and events.
25
Benefits of Promises
Benefits of Promises
• Improves Code Readability
• Better handling of asynchronous operations
• Better flow of control definition in asynchronous logic
• Better Error Handling
26
Benefits of Promises
Benefits of Promises
• Improves Code Readability
• Better handling of asynchronous operations
• Better flow of control definition in asynchronous logic
• Better Error Handling
27
Why Are They Useful?
28
States of Promises
29
Using Promises
30
Using Promises
Let’s look at creating a consuming a let isMomHappy = false;
31
Using Promises // Define the Promise
let willIGetNewPhone = new Promise(function(resolve, reject) {
We can use a shortcut to if (isMomHappy) {
defining promises: var phone = {
brand: 'Samsung’,
color: 'black’
};
resolve(phone); // fulfilled
} else {
var reason = new Error('mom is not happy’);
reject(reason); // reject
}
});
32
Chaining Promises let isMomHappy = false;
33
34
Catching Errors
35
36
Converting Callbacks to Promises
We will use a node package called
bluebird to convert methods that
take callbacks to methods that
return promises.
To convert one method, we use
bluebird’s promisify method; to
convert each method in an object,
we use promisifyAll
This will make a copy of each
method, that ends with the term
Async and returns a promise.
37
Converting a Callback to a Promise
Rather than using callbacks, many people opt to convert their methods to return
promises, even if they use code that internally uses callback.
There are two strategies for converting converting callbacks to promises. Let us take, for
example, converting fs.readFile from a callback to a promise:
• Manually writing a method that returns a promise, which internally calls
fs.readFile
• Using a promise library, such as bluebird, to make a copy of fs that has methods
auto generated to return promises. It will make a method called readFileAsync,
which returns a promise.
This concept is called colloquially known as promisifying an operation.
38
Example 2: Reading Files With Promises
39
Our Goal
We are now going to convert the previous script to perform the same operation,
however this time we will use promises.,
1. We will first use Bluebird to promisify the entirety of fs and prompt.
2. We will then perform our goals from before, this time using promises.
You can see this code demonstrated in the promise folder.
40
Async/Await
41
Asynchronous Code Is Messy
As a result, over the last several years, the JavaScript language has added a concept of
async functions and awaiting the end of an asynchronous operation.
42
Async Functions
A function can be defined as an async function, which means that the function will
automatically return a promise (even if there are no asynchronous operation in that
function).
• By marking a function as async, you allow the await keyword to be used inside of the
function.
Besides their ability to await promises and their guaranteed returning of a promise,
there is no difference between a function and an async function.
You can ONLY use the await keyword inside an async function and at the top
level of a module.
43
Awaiting Promises
44
Example
On the top, we see promises. On the
bottom, we see the same code written
in async/await notation.
45
What Benefit Does It Have?
By using async and await we can create code that is written and read in the order that
which the operations will complete, while still allowing the functions themselves to be
asynchronous.
Internally, the functions that run async code will still be constantly giving up execution
cycles to perform other operations while they continue their tasks, however your code
can abstract over that.
46
Example 3: Reading Files With
Async/Await
47
Our Goal
We are now going to convert the previous script to perform the same operation,
however this time we will use async/await.,
1. We will still use Bluebird to promisify the entirety of fs and prompt.
2. We will then perform our goals from before, this time using promises.
You can see this code demonstrated in the async-await folder.
48
Questions?
49