Understand promises before you start using async/await

What even is a promise?

function getFirstUser() {
return getUsers().then(function(users) {
return users[0].name;
});
}
function getFirstUser() {
return getUsers().then(function(users) {
return users[0].name;
}).catch(function(err) {
return {
name: 'default user'
};
});
}

Cool… so how does async/await tie in?

async function getFirstUser() {
let users = await getUsers();
return users[0].name;
}
async function getFirstUser() {
try {
let users = await getUsers();
return users[0].name;
} catch (err) {
return {
name: 'default user'
};
}
}

Pitfall 1: not awaiting

let user = await getFirstUser();
let user = getFirstUser();

Pitfall 2: awaiting multiple values

let foo = await getFoo();
let bar = await getBar();
let [foo, bar] = await* [getFoo(), getBar()];
let [foo, bar] = await Promise.all([getFoo(), getBar()]);
[getFoo(), getBar()]
let fooPromise = getFoo();
let barPromise = getBar();
let foo = await fooPromise;
let bar = await barPromise;
  1. First. we dispatch `getFoo` and `getBar` and save the promises they return in `fooPromise` and `barPromise`.
  2. These actions are now in progress, they’re happening, there’s no stopping them or delaying them
  3. We await each promise in turn

Pitfall 3: your whole stack needs to be async

function getFirstUser(callback) {
return getUsers().then(function(users) {
return callback(null, users[0].name);
}).catch(function(err) {
return callback(err);
});
}
function getFirstUser(callback) {
return getUsers().then(function(users) {
return users[0].name;
}).nodeify(callback);
}
function callbackToPromise(method, ...args) {
return new Promise(function(resolve, reject) {
return method(...args, function(err, result) {
return err ? reject(err) : resolve(result);
});
});
}
async function getFirstUser() {
let users = await callbackToPromise(getUsers);
return users[0].name;
}

Pitfall 4: Gotta remember to handle errors

myApp.endpoint('GET', '/api/firstUser', async function(req, res) {
let firstUser = await getFirstUser();
res.json(firstUser)
});
myApp.endpoint('GET', '/api/firstUser', function(req, res) {
return getFirstUser().then(function(firstUser) {
res.json(firstUser)
});
});
myApp.registerEndpoint('GET', '/api/firstUser', async function(req, res) {
try {
let firstUser = await getFirstUser();
res.json(firstUser)
} catch (err) {
console.error(err);
res.status(500);
}
});

--

--

--

works for PayPal, as a lead engineer in Checkout. Opinions expressed herein belong to him and not his employer. daniel@bluesuncorp.co.uk

Love podcasts or audiobooks? Learn on the go with our new app.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Daniel Brain

Daniel Brain

works for PayPal, as a lead engineer in Checkout. Opinions expressed herein belong to him and not his employer. daniel@bluesuncorp.co.uk

More from Medium

Intuitive Code

An open Apple laptop, notebook, tea cup and saucer on a wooden table

Operators, Scope, and Functions.

SOLID Principles, JavaScript, Version Controlling and NoSQL

4 Ways to Handle Async Operations in Javascript

4 Ways to Handle Async Operations in Javascript