Last active
October 20, 2017 20:58
-
-
Save protometa/fe8032f8e910e2acdec4fe89adab5939 to your computer and use it in GitHub Desktop.
Async In Javascript
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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