Home United States USA — software How to Interact With a Database Using Promises in Node.js How to...

How to Interact With a Database Using Promises in Node.js How to Interact With a Database Using Promises in Node.js

273
0
SHARE

Get an overview of promises, learn about " then" + " catch" and " resolve" + " reject, " learn what promise chaining is, and look at a Promise demo application.
The first two patterns we looked at in this series were Node.js callbacks and the Async module. While effective, those patterns are not the only ways of writing asynchronous code. Patterns built around concepts such as “deferreds” and “promises” were first introduced to the JavaScript community via third-party libraries like Q and Bluebird. Over time a native implementation of promises was added to ECMAScript, then implemented in V8, and later integrated into Node.js.
Promises are important to learn because many modules use them in their APIs. Also, they are integral to async functions, which I’ ll cover in the next part of the series. This post will cover the basics of promises and demonstrate how they can be used to construct asynchronous applications.
Native support for promises was added to JavaScript via the Promise object. The Promise object is a constructor function that’s used to create new promise instances. Promise instances have two important properties: state and value. Let’s take a look at how we can manipulate those values and respond to state changes.
When a new promise is created, the constructor function accepts a “resolver” function that should have two formal parameters: resolve and reject. When the resolver function is executed, which happens immediately when creating new instances, these parameters will be functions that can transition the state of the promise and provide a value. Promises are typically resolved when the resolver completes successfully and rejected if an error occurs.
Here’s an example that shows several promise instances with different states and values:
If you run the above script in either a browser or Node.js, you should see console output similar to the comments. For now, ignore any errors related to uncaught or unhandled promise rejections (more on that later) .
The then method is typically used to specify what should happen when the promise is resolved, though it can accept a second function to handle rejections too. The catch method is explicitly used to handle rejections.
The callback functions passed to then and catch will receive the value passed through the when the resolve or reject functions are invoked in the resolver. The value passed through rejections should always be an instance of Error, though that’s not enforced.
Here’s an example that uses resolve and reject asynchronously. The then and catch methods are used to define what should happen when the promise’s state changes.
Here’s what’s going on in the script:
If you run the script above several times, you should see success messages and the occasional error message. Did you notice how the catch call flows off the then call? That technique is called promise chaining.
If you run the above script with Node.js or in a browser, you should see output like the following (I used Node.js) :
Things get more interesting when the value returned is a promise. When this happens, the next handler in the chain will not be invoked until that promise is resolved or rejected.
Here’s an example:
With a little luck, when you run the script, you should see three random values printed to the console every two seconds. If an “error” occurs at any point in the chain, the remaining then functions will be skipped and the error will be passed to the next error handler in the chain. As you can see, promise chaining is a great way to run async operations in series without running into callback hell. But what about more complex flows?
Asynchronous iteration of collections, something that’s quite trivial with Async, is not so easy with promises. I’ m not showing the technique here because there’s a much simpler way to do this now with async functions — just use a loop!
We’ ve already covered some of the basics regarding error handling in the section on promise chaining. In this section, I want to explain something that often trips up folks that are new to promises.
Have a look at this example:
Running the script above should give you output like the following:
Note that unhandled errors thrown in functions passed to then and catch are swallowed up and treated like rejections. This means the error will be passed to the next error handler in the chain. But what happens if there are no more error handlers?
The solution is simple enough: be sure to handle those rejections! Check out this excellent post by Valeri Karpov to learn more about unhandled rejections.
The promise demo app is comprised of the following four files. The files are also available via this Gist.
package.json:
This is a very basic package.json file. The only external dependency is oracledb.
index.js:
The db-config.js file is used in index.js to provide the connection info for the database. This configuration should work with the DB App Dev VM, but it will need to be adjusted for other environments.
employees.js:
I hope this post has helped you to understand how promises work in Node.js. Remember that understanding promises is essential to understanding async functions, which I’ ll cover in the next and final part of this series.

Continue reading...