Skip to content

Instantly share code, notes, and snippets.

@w3cj
Last active June 21, 2017 16:27
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save w3cj/823a94768cd6bfa6bc70ed4aa0858e09 to your computer and use it in GitHub Desktop.
Save w3cj/823a94768cd6bfa6bc70ed4aa0858e09 to your computer and use it in GitHub Desktop.

async/await

will change your life




By CJ R.

Lead Instructor @ Galvanize


Show of hands:

Who here writes JavaScript code daily?


Show of hands:

Who here deals with callbacks or promises daily?


JavaScript is an "A" word


Asynchronous


Callbacks

request('http://www.omdbapi.com/?s=star%20wars', (error, response, body) => {
	const results = JSON.parse(body);
	console.log(results);
});

"callback hell"

function getFirstMovie(callback) {
	// Make request to get ID
	request('http://www.omdbapi.com/?s=star%20wars', (error, response, body) => {
		const results = JSON.parse(body);
		//requires the ID of the previous request
		request('http://www.omdbapi.com/?i=' + results.Search[0].imdbID, (error, response, body) => {
			const movie = JSON.parse(body);
			callback(movie);
		});
	});
}

getFirstMovie(movie => {
	console.log(movie);
});

Promises to the rescue

// rp is the request-promise library
function getFirstMovie() {
	return rp('http://www.omdbapi.com/?s=star%20wars')
		.then(body => {
			const results = JSON.parse(body);
			return rp('http://www.omdbapi.com/?i=' + results.Search[0].imdbID)
		}).then(body => {
			const movie = JSON.parse(body);
			return movie;
		});
}

getFirstMovie()
	.then(movie => {
		console.log(movie);
	}).catch(error => {
		console.log('Error!!', error);
	});

Promise Basics

  • Represents a value that may or may not resolve in the future
  • Pass a callback to .then to be called when the promise is resolved
  • Pass a callback to .catch to be called when the promise is rejected

Promises are just cleaner callbacks

  • The rp function might be implemented like this:
function rp(url) {
	return new Promise((resolve, reject) => {
		request(url, (error, response, body) => {
			if(error) {
				reject(error);
			} else {
				resolve(body);
			}
		});
	});
}

Enter: async/await

  • Introduced in ES2016 (ES7)
async function getFirstMovie() {
	try {
		const resultsBody = await rp('http://www.omdbapi.com/?s=star%20wars');
		const results = JSON.parse(resultsBody);
		const movieBody = await rp('http://www.omdbapi.com/?i=' + results.Search[0].imdbID);
		const movie = JSON.parse(movieBody);
		return movie;
	} catch (error) {
		console.log('Error!', error);
	}

}

getFirstMovie()
	.then(movie => {
		console.log(movie);
	});


How does that work?


Async Functions

  • Add the async keyword to any function that will await a promise
async function doTheThing() {
	//stuff happens
}
  • When an async function is called, it returns a Promise.

    • The value returned is "resolved"
    • Any exception thrown is "rejected"
  • An async function can contain an await expression

    • This pauses the execution of the async function and waits for the passed Promise's resolution, and then resumes the async function's execution and returns the resolved value.

Promises

// rp is the request-promise library
function getFirstMovie() {
	return rp('http://www.omdbapi.com/?s=star%20wars')
		.then(body => {
			const results = JSON.parse(body);
			return rp('http://www.omdbapi.com/?i=' + results.Search[0].imdbID)
		}).then(body => {
			const movie = JSON.parse(body);
			return movie;
		});
}

getFirstMovie()
	.then(movie => {
		console.log(movie);
	}).catch(error => {
		console.log('Error!!', error);
	});

async/await

async function getFirstMovie() {
    try {
        const resultsBody = await rp('http://www.omdbapi.com/?s=star%20wars');
        const results = JSON.parse(resultsBody);
        const movieBody = await rp('http://www.omdbapi.com/?i=' + results.Search[0].imdbID);
        const movie = JSON.parse(movieBody);
        return movie;
    } catch (error) {
        console.log('Error!', error);
    }

}

getFirstMovie()
    .then(movie => {
        console.log(movie);
    });

async/await gotchas

  • Be wary of code that is too synchronous
async function doThings() {
	for (var i = 0; i < array.length; i++) {
		await doTheThing(array[i])
	}
}

Instead, use your promise know how:

async function doThings() {
	await Promise.all(array.map(item => {
		return doTheThing(item);
	}));
}

async/await support

  • Supported in Node.js 7.6.x


Conclusion

  1. Use async/await to make asynchronous code look synchronous
  2. ????
  3. Profit

Resources


Thanks!

CJ R.

cj on Denver Devs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment