Skip to content

Instantly share code, notes, and snippets.

@theefer
Last active September 26, 2016 17:21
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save theefer/6e9796b39acbf746613bf1f82e5ce443 to your computer and use it in GitHub Desktop.
Save theefer/6e9796b39acbf746613bf1f82e5ce443 to your computer and use it in GitHub Desktop.
// Given:
// getFullName(id) => Promise<String>
// getAvatarId(id) => Promise<int>
// getImageById(id) => Promise<String>
// ## Using promises without unnecessary nesting makes it more obvious what
// ## request depend on what other requests (they require async data) and
// ## everything is parallelised by default.
// (Good - parallel) Promises
function getUserInfo(userId) {
const fullNamePromise = getFullName(userId);
const avatarPromise = getAvatarId(userId).then(avatarId => {
return getImageById(avatarId);
});
return Promise
.all([fullNamePromise, avatarPromise])
.then(([fullName, avatar]) => ({fullName, avatar}));
}
// (Bad - sequential) Promises
function getUserInfo(userId) {
// Bad: unnecessary nesting
return getFullName(userId).then(fullName => {
return getAvatarId(userId).then(avatarId => {
return getImageById(avatarId);
}).then(avatar => {
return {fullName, avatar};
});
});
}
// ## Correct parallelisation can be achieved with async-await, but it
// ## requires extra care, an understanding of async/await, and the use
// ## of underlying Promise primitives (mixing concepts & abstraction layers).
// (Good parallel, with .then and Promise.all) async-await
async function getUserInfo(userId) {
const fullNamePromise = getFullName(userId);
// Note: requires mixing async-await with Promise#then and Promise.all
const avatarPromise = getAvatarId(userId).then(avatarId => getImageById(avatarId));
const [fullName, avatar] = await Promise.all([fullNamePromise, avatarPromise]);
return {fullName, avatar};
}
// (Good parallel, with helper function and Promise.all) async-await
async function getAvatar(userId) {
const avatarId = await getAvatarId(userId)
return await getImageById(avatarId);
}
async function getUserInfo(userId) {
const fullNamePromise = getFullName(userId);
const avatarPromise = getAvatar(userId);
const [fullName, avatar] = await Promise.all([fullNamePromise, avatarPromise]);
return {fullName, avatar};
}
// (Good parallel, but brittle) async-await
async function getUserInfo(userId) {
// Starts the first request without waiting on it
const fullNamePromise = getFullName(userId);
// Warning: order matters!
const avatarId = await getAvatarId(userId);
const avatar = await getImageById(avatarId);
const fullName = await fullNamePromise;
return {fullName, avatar};
}
// (Bad - sequential) async-await
async function getUserInfo(userId) {
// Bad: we don't start getAvatarId until getFullName returns
const fullName = await getFullName(userId);
const avatarId = await getAvatarId(userId);
const avatar = await getImageById(avatarId);
return {fullName, avatar};
}
// (Bad sequential, with helper function) async-await
async function getAvatar(userId) {
const avatarId = await getAvatarId(userId)
return await getImageById(avatarId);
}
async function getUserInfo(userId) {
const fullName = await getFullName(userId);
const avatar = await getAvatar(userId);
return {fullName, avatar};
}
// (Bad sequential) async-await
async function getUserInfo(userId) {
const fullNamePromise = getFullName(userId);
const avatarIdPromise = getAvatarId(userId);
const [fullName, avatarId] = await Promise.all([fullNamePromise, avatarIdPromise]);
// Bad: we may have been able to start this request before fullNamePromise returns
const avatar = await getImageById(avatarId);
return {fullName, avatar};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment