Skip to content

Instantly share code, notes, and snippets.

@max8hine
Created June 23, 2018 00:22
Show Gist options
  • Save max8hine/d71459faf50705f5252aa42566811d59 to your computer and use it in GitHub Desktop.
Save max8hine/d71459faf50705f5252aa42566811d59 to your computer and use it in GitHub Desktop.
The Long Road to Async/Await in JavaScript
/**
* https://www.youtube.com/watch?v=IZIcWl-jq_0
* The Long Road to Async/Await in JavaScript
*/
/* Synchronous Code (Single Stack) */
let result = sendMessage('001', 'yo')
console.log(result)
function sendMessage(userId, message) {
let user = getUser(userId) // represent more complex user object.\
let able = canSend(user) // return true/false
if (!able) return false
return writeMessage(user, message)
}
/* Phase 1: Callbacks - continuation pattern */
sendMessage('001', 'hi', (err, result) => {
if (err) return err
console.log(result)
})
function sendMessage(userId, message, cb) {
getUser(userId, (err, user) => {
errCheck(err)
canSend(user, (err, able) => {
errCheck(err)
if (!able) { cb(null, false); return }
writeMessage(user, message, cb)
})
})
}
/* Phase 2: Promises */
sendMessage('001', 'hi')
.then(result => log(result))
.catch(err => errCheck(err))
function sendMessage(userId, message) {
// return Promise.reject(new Error('Bad Stuff'))
return getUser(userId)
.then(user => canSend(user))
.then((able) => {
if (!able) return false
return writeMessage(user, message)
})
.catch(err => errCheck(err))
}
/* Phase 3: Generators/Yield */
// Implementation 1 Generators/Yield - Raw
let gen = sendMessageGen('001', 'hi')
gen.next().value.then((user) => {
return gen.next(user).value.then((able) => {
return gen.next(able).value.then((result) => {
log(result)
})
})
})
function * sendMessageGen(userId, message) {
// yield Promise.reject(new Error('Bad Stuff'))
let user = yield getUser(userId)
let able = yield canSend(user)
if (!able) return false
return writeMessage(user. message)
}
// Implementation 2 Generators/Yield + Co
sendMessage('001', 'hi')
.then(result => log(result))
.catch(err => errCheck(err))
const co = require('co')
function sendMessage(userId, message) {
return co(sendMessageGen(userId, message))
}
/* Phase 4: Async/Await */
(async () => {
try {
let result = await sendMessage('001', 'hi')
} catch (error) {
errCheck(error)
}
log(result)
})()
async function sendMessage(userId, message) {
// throw new Error('Bad Stuff')
let user = await getUser(userId)
let able = await canSend(user)
if (!able) return false
return writeMessage(user, message)
}
// Node API Promisification
const util = require('util')
const pifall = require('pifall')
const fs = require('fs')
const readFile = util.promisify(fs.readFile)
// writhing more procedural code
(async () => {
/* Anti Practices
let stuff = await readFile('stuff.txt')
let data = await fs.readFileAsync('data.txt')
*/
let [stuff, data] = await Promise.all([ // Parallel
readFile('stuff.txt'),
fs.readFileAsync('data.txt')
])
log(`${stuff}, ${data}`)
})()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment