Skip to content

Instantly share code, notes, and snippets.

@protometa
Last active October 20, 2017 20:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save protometa/fe8032f8e910e2acdec4fe89adab5939 to your computer and use it in GitHub Desktop.
Save protometa/fe8032f8e910e2acdec4fe89adab5939 to your computer and use it in GitHub Desktop.
Async In Javascript
const {
queryDatabaseSync,
httpGetSync,
writeFileSync,
queryDatabase,
httpGet,
writeFile
} = require('./mocks.js')
// synchronous:
try {
// get a record from database containing a url
var url = queryDatabaseSync()
// use url found in result to make http request
var data = httpGetSync(url)
// use fetched data to write file
writeFileSync(data)
} catch (err) {
// errors at any step along the way can be handled here
// note: catching just to throw is silly
// uncaught sync errors will always be thrown but bear with me
throw err
}
console.log('synchronous: success!')
// synchronous - simplified functional:
try {
writeFileSync(httpGetSync(queryDatabaseSync()))
} catch (err) {
// errors at any step can be handled here
throw err
}
console.log('synchronous - simplified functional: success!')
// asynchronous with callbacks:
// note: the errors must be handled or thrown in async code or they are lost
queryDatabase((err, url) => {
if (err) throw err // must handle queryDatabase error here
httpGet(url, (err, data) => {
if (err) throw err // must handle httpGet error here
writeFile(data, (err) => {
if (err) throw err // must handle writeFile error here
console.log('asynchronous with callbacks: success!')
})
})
})
// asynchronous with returned promises:
// (usually not done this way, but illustrates that something is returned immediately like with sync code)
var urlPromise = queryDatabase()
var dataPromise = urlPromise.then((url) => {
return httpGet(url)
})
var filePromise = dataPromise.then((data) => {
return writeFile(data)
})
filePromise.then(() => {
console.log('asynchronous with returned promises: success!')
}, (err) => {
// all errors must be handled here
throw err
})
// asynchronous with promises - chained:
// note: with promises any of these steps can actually be synchronous as well!
// .then() always returns a promise
queryDatabase().then((url) => {
return httpGet(url)
}).then((data) => {
return writeFileSync(data) // <- mixing in a sync call
}).then(() => {
console.log('asynchronous with promises - chained: success!')
}).catch((err) => {
throw err
})
// async (or sync) with promises - simplified:
queryDatabase().then(httpGet).then(writeFileSync).then(function () {
console.log('async (or sync) with promises - simplified: success!')
}).catch(function (err) {
throw err
})
// async with async/await keywords (sugar coated promises):
async function doStuff () {
var url = await queryDatabase()
var data = await httpGet(url)
return writeFile(data)
}
// doStuff() just returns a promise
// it can be handled with a `.then()`, or if called in another `async` function you can `await` it
doStuff().then(function () {
console.log('async with async/await keywords: success!')
}).catch(function (err) {
throw err
})
// sync functions
exports.queryDatabaseSync = () => {
return 'url'
}
exports.httpGetSync = (url) => {
if (url !== 'url') {
throw new Error('invalid arguments')
}
return 'data'
}
exports.writeFileSync = (data) => {
if (data !== 'data') {
throw new Error('invalid arguments')
}
}
// async functions
// illustrates both callback and promise implimentation
// uses callbacks if provided otherwise returns promise
exports.queryDatabase = (cb) => {
if (cb) {
// callback implimentation
cb(null, 'url')
} else {
// promise implimentation
return Promise.resolve('url')
}
}
exports.httpGet = (url, cb) => {
if (cb) {
// callback implimentation
if (url !== 'url') {
return cb(new Error('invalid arguments'))
}
cb(null, 'data')
} else {
// promise implimentation
return new Promise((resolve, reject) => {
if (url !== 'url') {
return reject(new Error('invalid arguments'))
}
resolve('data')
})
}
}
exports.writeFile = (data, cb) => {
if (cb) {
// callback implimentation
if (data !== 'data') {
return cb(new Error('invalid arguments'))
}
cb()
} else {
// promise implimentation
return new Promise((resolve, reject) => {
if (data !== 'data') {
return reject(new Error('invalid arguments'))
}
resolve()
})
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment