Promises and Async

Asynchrony in JavaScript

Asynchrony in JavaScript

What is multitasking?

Multitasking in JS

Multitasking (concurrency) is usually achieved by multithreading or multiprocessing.
A JavaScript program runs on a single thread!
But the host environment (node.js/browsers/etc.) allows us to achieve a kind of multitasking programs using asynchronous code execution
More on asyncronous JavaScript, eventloop: Understanding Asynchronous JavaScript

Synchronous vs. Asynchronous Overview

Synchronous vs. Asynchronous Demo


		// generate array of integers - needed for tests bellow:
		let testArrays = [
			Array.from({length:1_000_000},(_,i)=>i+1),
			Array.from({length:2_000_000},(_,i)=>i+1),
			Array.from({length:3_000_000},(_,i)=>i+1),
		];
		function syncDemo(){
			console.time('syncDemo');
			testArrays.forEach(arr=>{
				console.log(arr.reduce((ac, el)=>ac+el));
			})
			console.timeEnd('syncDemo');
		}
		function asyncDemo(){
			//setTimeout is executed asynchronous and is not blocking the rest of the code!
			console.time('asyncDemo');
			testArrays.forEach(arr=>{
				setTimeout(()=>{console.log( arr.reduce((ac, el)=>ac+el) )}, 0)
			})
			console.timeEnd('asyncDemo');
		}

		console.log(`~~~~~ Sync execution ~~~~~`);
		syncDemo();

		console.log(`\n~~~~~ Async execution ~~~~~`);
		asyncDemo();

		// ~~~~~ Sync execution ~~~~~
		// 500000500000
		// 2000001000000
		// 4500001500000
		// syncDemo: 176.295ms
		//
		// ~~~~~ Async execution ~~~~~
		// asyncDemo: 0.411ms
		// 500000500000
		// 2000001000000
		// 4500001500000
  	

Why Using Promises?

Why Using Promises?

The problem

Let's have to build a program which will:
prepareDinner() and if it is fulfilled, then
eatDinner() and if it is fulfilled, then
goToBed()
Examine the next code. It works as we want, but calling a function into another function is a bad practice
no separation of concerns
spaghetti code

Solution with callbacks

To separate the concerns we can use callback functions, but the code is still difficult to mange. In fact, this is what is called a callback hell:

Solution with Promises

Next code is definitely cleaner

Promises

Promises

Overview

A Promise is an object representing the eventual completion or failure of an asynchronous operation
Essentially, a promise is a returned object to which you attach callbacks, instead of passing callbacks into a function.
A promise can either be fulfilled with a value or rejected with a reason (error)
A promise object has method then() which accepts two callback functions and returns a promise object (which means that we can chain multiple then() calls)
Once a Promise is fulfilled or rejected, the respective handler function (onFulfilled or onRejected) will be called asynchronously

			// create Promise object:
			const p = new Promise((resolve, reject)=>{
				// do promised work asynchronously, like getting data
				setTimeout(() => {
					const data = 'some data';

					if(data){
						resolve(data)
					}else{
						reject('Error')
					}
				}, 1000);
			});

			// use promise:
			p.then(value => {
				console.log(value);
			}, reason => {
				console.error(reason);
			});
		

Async/Await

Async/Await

Overview

Async/await is a syntactic feature that allows writing asynchronous code in a more synchronous manner. It's built on top of Promises.
An async function always returns a Promise.
The await keyword can be used inside async functions to pause the execution until the Promise is resolved.

			let getDataPromise = new Promise((resolve, reject) => {
				setTimeout(() => {
					resolve('Some data');
					// reject('Error message');
				}, 1000);
			});

			async function renderData() {
				try {
					const data = await getDataPromise
					console.log(data);
				} catch (error) {
					console.error(error);
				}
			}

			renderData();
		

Async/Await API vs Promise API


			let getDataPromise = new Promise((resolve, reject) => {
				setTimeout(() => {
					// resolve('Some data');
					reject('Can not get data!');
				}, 1000);
			});
			// using getDataPromise with Async/Await API:
			async function renderData() {
				try {
					const data = await getDataPromise
					console.log(data);
				} catch (error) {
					console.error(error);
				}
			}

			// using getDataPromise with Promise API:
			function renderData() {
				getDataPromise
				.then(data=>console.log(data))
				.catch(err=>console.log(err))
			}

			renderData();
		

References

References

Docs

Using promises @mdn
Promise Constructor @mdn
An Overview of JavaScript Promises @sitepoint.com

These slides are based on

customised version of

Hakimel's reveal.js

framework