Categories
Modern JavaScript

Best of Modern JavaScript — Promise Mistakes to Avoid

Spread the love

Since 2015, JavaScript has improved immensely.

It’s much more pleasant to use it now than ever.

In this article, we’ll look at JavaScript promise mistakes we should avoid.

Chaining and Errors

We can have one or more then calls in a chain.

If we have multiple then calls that don’t have error handlers, then the error is passed on until there’s an error handler.

So if we have:

asyncFunc1()
  .then(asyncFunc2)
  .then(asyncFunc3)
  .catch(function(reason) {
    // ...
  });

Then catch will be called if any of the promises in the chain has an error.

Common Mistakes

A promise chain can be built with a chain of then calls.

One way we can make a mistake is that we return the original promise instead of the promise that’s returned from then .

For example, we shouldn’t write:

function foo() {
  const promise = promiseFunc();
  promise.then(result => {
    //....
  });

  return promise;
}

Instead, we should write:

function foo() {
  const promise = promiseFunc();
  return promise.then(result => {
    //...
  });
}

We got to return the promise chain instead of the original promise.

Nesting Promises

We should never nest promises. The whole point of using promises is to avoid nesting.

For example, if we have something like:

promiseFunc1()
  .then(result1 => {
    promiseFunc2()
      .then(result2 => {
        //...
      });
  });

We should rewrite it to:

promiseFunc1()
  .then(result1 => {
    return promiseFunc2();
  })
  .then(result2 => {
    //...
  });

Creating Promises Instead of Chaining

We shouldn’t create promises instead of chaining.

So instead of creating promises the Promise constructor:

function insert(entry) {
  return new Promise((resolve, reject) => {
    db.insert(entry)
      .then(resultCode => {
        //...
        resolve(resultCode);
      }).catch(err => {
        reject(err);
      })
  });
}

We just return the promise chain:

function insert(entry) {
  return db.insert(entry)
    .then(resultCode => {
      //...
    }).catch(err => {
      handleError(err);
    })
}

What we shouldn’t do is create a new promise by using the Promise constructor.

then already returns a promise, so we don’t need the Promise constructor.

Using then() for Error Handling

then shouldn’t be used for handing.

catch(callback) is short for then(null, callback) .

However, using in the same line is problematic.

The error callback in the then method doesn’t catch errors that occur in the rejection by the fulfillment callback.

For instance, if we have:

promiseFunc1()
  .then(
    value => {
      fooo();
      return promiseFunc2();
    },
    error => {
      //...
    });

If an error occurs in the first then callback, the 2nd one won’t catch it.

Error Handling

There’re 2 kinds of errors that can occur.

Operational errors happen when a correct program encounters an exceptional situation.

For example, if someone enters something in an invalid format, then that’s an operational error.

A programmer error is an incorrect behavior in our program.

For instance, we may be passing in an array to a function when it actually expects a string, then that’s a programmer error.

To handle operational errors, we should either throw exceptions or invoke rejections.

If it’s a programmer error, then the program should fail quickly.

We can throw an exception to make it clear that the program failed.

Conclusion

There’re many common mistakes that we should avoid with promises.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *