{"id":2982,"date":"2025-01-07T15:03:26","date_gmt":"2025-01-07T21:03:26","guid":{"rendered":"https:\/\/readme.com\/resources\/?p=2982"},"modified":"2025-01-07T15:03:28","modified_gmt":"2025-01-07T21:03:28","slug":"using-async-await-in-node-js-7-6-0","status":"publish","type":"post","link":"https:\/\/readme.com\/resources\/using-async-await-in-node-js-7-6-0","title":{"rendered":"Using async\/await in Node.js 7.6.0"},"content":{"rendered":"\n<p>Last week saw the release of Node.js v7.6.0 which contained (amongst other things) an update to v8 5.5 (Node&#8217;s underlying JS engine). This v8 release includes a brand new language feature: async functions. Utilising this new feature is done through 2 new keywords:&nbsp;<code>async<\/code>&nbsp;and&nbsp;<code>await<\/code>. Async functions are not new in the JS world and it has been possible to use them via transpilers (babel) for some time, but having them natively in the language means their use will become much more widespread.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"sowhatisanasyncfunction\">So what is an async function?<\/h2>\n\n\n\n<p>Async functions makes promise-using code more readable than before. Now instead of using&nbsp;<code>Promise.then()<\/code>&nbsp;to resolve your promise to a value, you can just prefix the promise with&nbsp;<code>await<\/code>&nbsp;and your code magically pauses until the value is available, then proceeds with execution as if the value were synchronous all along. To allow this to happen, you need to use the&nbsp;<code>async<\/code>&nbsp;keyword on the enclosing function.<\/p>\n\n\n\n<p>Here&#8217;s a before and after example of some code encrypting a password using bcrypt and updating a user&#8217;s password to the hash:<\/p>\n\n\n\n<p>Before:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"JavaScript\" class=\"language-JavaScript\">schema.pre('save', function hashPassword(next) {\n  const user = this;\n\n  \/\/ only hash the password if it has been modified (or is new)\n  if (!user.isModified('password')) return next();\n\n  \/\/ generate a salt\n  return bcrypt.genSalt(10).then((salt) =&gt; {\n    \/\/ hash the password along with our new salt\n    return bcrypt.hash(user.password, salt).then((hash) =&gt; {\n      \/\/ override the cleartext password with the hashed one\n      user.password = hash;\n      return next();\n    }).catch(next);\n  }).catch(next);\n});\n<\/code><\/pre>\n\n\n\n<p>And heres the same code as before rewritten to use async functions:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"JavaScript\" class=\"language-JavaScript\">schema.pre('save', async function hashPassword(next) {\n  try {\n    const user = this;\n\n    \/\/ only hash the password if it has been modified (or is new)\n    if (!user.isModified('password')) return next();\n\n    \/\/ generate a salt\n    const salt = await bcrypt.genSalt(10);\n\n    \/\/ hash the password along with our new salt\n    const hash = await bcrypt.hash(user.password, salt);\n\n    \/\/ override the cleartext password with the hashed one\n    user.password = hash;\n    return next();\n  } catch (e) {\n    return next(e);\n  }\n});\n<\/code><\/pre>\n\n\n\n<p>Note the&nbsp;<code>async<\/code>&nbsp;keyword before the function, and&nbsp;<code>await<\/code>&nbsp;when we need to resolve a promise to a value.<\/p>\n\n\n\n<p>This code is flatter and easier to reason about. Error handling is performed using a single&nbsp;<code>try..catch<\/code>&nbsp;block as opposed to adding&nbsp;<code>.catch(next)<\/code>&nbsp;to the end of each promise.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"caveats\">Caveats<\/h2>\n\n\n\n<p>There are some caveats to using this approach. If you&#8217;re not using promises everywhere already, then you&#8217;ll need to wrap your calling code in a function then execute this function as a promise. Consider the following express route handler to fetch a user by id:<\/p>\n\n\n\n<p>Before async functions:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"JavaScript\" class=\"language-JavaScript\">app.get('\/:id', (req, res, next) =&gt; {\n  User.findById(req.params.id).then(user =&gt; {\n    res.json(user)\n  }).catch(next)\n})\n<\/code><\/pre>\n\n\n\n<p>Because express isn&#8217;t promise-aware, you have to use a wrapping function to catch any errors and pass them onto&nbsp;<code>next<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"JavaScript\" class=\"language-JavaScript\">app.get('\/:id', (req, res, next) =&gt; {\n  async function action() {\n    const user = await User.findById(req.params.id)\n    res.json(user)\n  }\n  action().catch(next)\n})\n<\/code><\/pre>\n\n\n\n<p>This is a little cleaner, but has the same level of nesting as before. This can be improved using a simple little helper function, to make express become promise-aware:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"JavaScript\" class=\"language-JavaScript\">function asyncWrap(fn) {\n  return (req, res, next) =&gt; {\n    fn(req, res, next).catch(next);\n  };\n};\n\napp.get('\/:id', asyncWrap(async (req, res) =&gt; {\n  const user = await User.findById(req.params.id)\n  res.json(user)\n})\n<\/code><\/pre>\n\n\n\n<p>This unifies the error handling to a single place and keeps it out of the route handler. If&nbsp;<code>User.findById()<\/code>&nbsp;throws an error, it&#8217;ll bubble up and get passed along to the error middleware as you&#8217;d expect.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"toconclude\">To conclude<\/h2>\n\n\n\n<p>I think&nbsp;<code>async\/await<\/code>&nbsp;are game changers for the JS language. Although it&#8217;s possible to write clean code using callbacks and promises, it can muddy the intent when it comes to error checking (either through repeated&nbsp;<code>if (err) return cb(err)<\/code>&nbsp;or&nbsp;<code>.catch(cb)<\/code>&nbsp;calls). Conversely however,&nbsp;<code>async\/await<\/code>&nbsp;makes it really easy to write code with lots of async operations which could cause performance issues and be signs of deeper architectural problems within your program.<\/p>\n\n\n\n<p>Node.js 7.6.0 changelog:&nbsp;<a href=\"https:\/\/github.com\/nodejs\/node\/blob\/master\/doc\/changelogs\/CHANGELOG_V7.md?ref=blog.readme.com#2017-02-21-version-760-current-italoacasas\">https:\/\/github.com\/nodejs\/node\/blob\/master\/doc\/changelogs\/CHANGELOG_V7.md#2017-02-21-version-760-current-italoacasas<\/a><br>v8 5.5 changelog:&nbsp;<a href=\"https:\/\/v8project.blogspot.com\/2016\/10\/v8-release-55.html?ref=blog.readme.com\">https:\/\/v8project.blogspot.com\/2016\/10\/v8-release-55.html<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Last week saw the release of Node.js v7.6.0 which contained (amongst other things) an update to v8 5.5 (Node&#8217;s underlying JS engine). This v8 release includes a brand new language feature: async functions. Utilising this new feature is done through 2 new keywords:&nbsp;async&nbsp;and&nbsp;await. Async functions are not new in the JS world and it has [&hellip;]<\/p>\n","protected":false},"author":4,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"content-type":"","inline_featured_image":false,"footnotes":""},"categories":[22],"tags":[],"ppma_author":[53],"class_list":["post-2982","post","type-post","status-publish","format-standard","hentry","category-api-tips"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v23.0 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Using async\/await in Node.js 7.6.0<\/title>\n<meta name=\"description\" content=\"Master async\/await in Node.js 7.6+! Learn how to simplify asynchronous code, refactor with clean examples, and handle errors seamlessly in Express apps.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/readme.com\/resources\/using-async-await-in-node-js-7-6-0\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Using async\/await in Node.js 7.6.0\" \/>\n<meta property=\"og:description\" content=\"Master async\/await in Node.js 7.6+! Learn how to simplify asynchronous code, refactor with clean examples, and handle errors seamlessly in Express apps.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/readme.com\/resources\/using-async-await-in-node-js-7-6-0\" \/>\n<meta property=\"og:site_name\" content=\"ReadMe: Resource Library\" \/>\n<meta property=\"article:published_time\" content=\"2025-01-07T21:03:26+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-01-07T21:03:28+00:00\" \/>\n<meta name=\"author\" content=\"Dom Harrington\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Miche Nickolaisen\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"2 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/readme.com\/resources\/using-async-await-in-node-js-7-6-0\",\"url\":\"https:\/\/readme.com\/resources\/using-async-await-in-node-js-7-6-0\",\"name\":\"Using async\/await in Node.js 7.6.0\",\"isPartOf\":{\"@id\":\"https:\/\/readme.com\/resources\/#website\"},\"datePublished\":\"2025-01-07T21:03:26+00:00\",\"dateModified\":\"2025-01-07T21:03:28+00:00\",\"author\":{\"@id\":\"https:\/\/readme.com\/resources\/#\/schema\/person\/770bcc036178743133b5ba515195981b\"},\"description\":\"Master async\/await in Node.js 7.6+! Learn how to simplify asynchronous code, refactor with clean examples, and handle errors seamlessly in Express apps.\",\"breadcrumb\":{\"@id\":\"https:\/\/readme.com\/resources\/using-async-await-in-node-js-7-6-0#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/readme.com\/resources\/using-async-await-in-node-js-7-6-0\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/readme.com\/resources\/using-async-await-in-node-js-7-6-0#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/readme.com\/resources\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Using async\/await in Node.js 7.6.0\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/readme.com\/resources\/#website\",\"url\":\"https:\/\/readme.com\/resources\/\",\"name\":\"ReadMe: Resource Library\",\"description\":\"Making API documentation better for everyone\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/readme.com\/resources\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/readme.com\/resources\/#\/schema\/person\/770bcc036178743133b5ba515195981b\",\"name\":\"Miche Nickolaisen\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/readme.com\/resources\/#\/schema\/person\/image\/a24e32f88df84934c107cef6fa8d3223\",\"url\":\"https:\/\/readme.com\/resources\/wp-content\/uploads\/2024\/06\/IMG_7151-scaled-e1718387764646.jpg\",\"contentUrl\":\"https:\/\/readme.com\/resources\/wp-content\/uploads\/2024\/06\/IMG_7151-scaled-e1718387764646.jpg\",\"caption\":\"Miche Nickolaisen\"},\"description\":\"An Austin resident since 2009, Miche grew up in rural southwestern Missouri. When not working on ReadMe's content marketing, you can find them doing a number of hobbies, including (but not limited to) bouldering, martial arts, playing tabletop RPGs and\/or video games, bullet journaling, and making art. They live with a large menagerie of indoor pets and a smaller (outdoor) menagerie of feral cats they take care of (sometimes including a few possums and raccoons, just for good measure).\",\"url\":\"https:\/\/readme.com\/resources\/author\/miche\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Using async\/await in Node.js 7.6.0","description":"Master async\/await in Node.js 7.6+! Learn how to simplify asynchronous code, refactor with clean examples, and handle errors seamlessly in Express apps.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/readme.com\/resources\/using-async-await-in-node-js-7-6-0","og_locale":"en_US","og_type":"article","og_title":"Using async\/await in Node.js 7.6.0","og_description":"Master async\/await in Node.js 7.6+! Learn how to simplify asynchronous code, refactor with clean examples, and handle errors seamlessly in Express apps.","og_url":"https:\/\/readme.com\/resources\/using-async-await-in-node-js-7-6-0","og_site_name":"ReadMe: Resource Library","article_published_time":"2025-01-07T21:03:26+00:00","article_modified_time":"2025-01-07T21:03:28+00:00","author":"Dom Harrington","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Miche Nickolaisen","Est. reading time":"2 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/readme.com\/resources\/using-async-await-in-node-js-7-6-0","url":"https:\/\/readme.com\/resources\/using-async-await-in-node-js-7-6-0","name":"Using async\/await in Node.js 7.6.0","isPartOf":{"@id":"https:\/\/readme.com\/resources\/#website"},"datePublished":"2025-01-07T21:03:26+00:00","dateModified":"2025-01-07T21:03:28+00:00","author":{"@id":"https:\/\/readme.com\/resources\/#\/schema\/person\/770bcc036178743133b5ba515195981b"},"description":"Master async\/await in Node.js 7.6+! Learn how to simplify asynchronous code, refactor with clean examples, and handle errors seamlessly in Express apps.","breadcrumb":{"@id":"https:\/\/readme.com\/resources\/using-async-await-in-node-js-7-6-0#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/readme.com\/resources\/using-async-await-in-node-js-7-6-0"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/readme.com\/resources\/using-async-await-in-node-js-7-6-0#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/readme.com\/resources\/"},{"@type":"ListItem","position":2,"name":"Using async\/await in Node.js 7.6.0"}]},{"@type":"WebSite","@id":"https:\/\/readme.com\/resources\/#website","url":"https:\/\/readme.com\/resources\/","name":"ReadMe: Resource Library","description":"Making API documentation better for everyone","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/readme.com\/resources\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/readme.com\/resources\/#\/schema\/person\/770bcc036178743133b5ba515195981b","name":"Miche Nickolaisen","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/readme.com\/resources\/#\/schema\/person\/image\/a24e32f88df84934c107cef6fa8d3223","url":"https:\/\/readme.com\/resources\/wp-content\/uploads\/2024\/06\/IMG_7151-scaled-e1718387764646.jpg","contentUrl":"https:\/\/readme.com\/resources\/wp-content\/uploads\/2024\/06\/IMG_7151-scaled-e1718387764646.jpg","caption":"Miche Nickolaisen"},"description":"An Austin resident since 2009, Miche grew up in rural southwestern Missouri. When not working on ReadMe's content marketing, you can find them doing a number of hobbies, including (but not limited to) bouldering, martial arts, playing tabletop RPGs and\/or video games, bullet journaling, and making art. They live with a large menagerie of indoor pets and a smaller (outdoor) menagerie of feral cats they take care of (sometimes including a few possums and raccoons, just for good measure).","url":"https:\/\/readme.com\/resources\/author\/miche"}]}},"authors":[{"term_id":53,"user_id":0,"is_guest":1,"slug":"dom-harrington","display_name":"Dom Harrington","avatar_url":{"url":"https:\/\/readme.com\/resources\/wp-content\/uploads\/2024\/06\/1516897618298.jpeg","url2x":"https:\/\/readme.com\/resources\/wp-content\/uploads\/2024\/06\/1516897618298.jpeg"},"first_name":"Dom","last_name":"Harrington","position":"Open Source Engineer","slogan":"","description":"Dom joins the ReadMe team remotely from the UK. He enjoys cooking, long walks in the countryside and playing video games. You\u2019ll likely find him in ReadMe's open source repos frantically writing tests."}],"_links":{"self":[{"href":"https:\/\/readme.com\/resources\/wp-json\/wp\/v2\/posts\/2982","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/readme.com\/resources\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/readme.com\/resources\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/readme.com\/resources\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/readme.com\/resources\/wp-json\/wp\/v2\/comments?post=2982"}],"version-history":[{"count":0,"href":"https:\/\/readme.com\/resources\/wp-json\/wp\/v2\/posts\/2982\/revisions"}],"wp:attachment":[{"href":"https:\/\/readme.com\/resources\/wp-json\/wp\/v2\/media?parent=2982"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/readme.com\/resources\/wp-json\/wp\/v2\/categories?post=2982"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/readme.com\/resources\/wp-json\/wp\/v2\/tags?post=2982"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/readme.com\/resources\/wp-json\/wp\/v2\/ppma_author?post=2982"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}