Ville Miekk-oja Ville Miekk-oja - 2 months ago 4x
Node.js Question

Understanding promise chains

I'm using Promises in NodeJS project, and would like to understand Promise.chains better.

I have one exposed function:

Main library function, that I want my users to call. It will return a promise, and the users then need to handle the resolve and reject's.

That Main library function will call many other library functions, which I want to chain. So each of those functions will return a promise like so:

mainLibraryFunction = function (arguments...) {
return this.firstLibraryFn().then(secondLibraryFn).then(thirdLibraryFn)...

Each of these will return a promise, that can be either reject or resolve. What I would want is that if any of the library functions rejects, then instead passing the reject to the next function, I would like to return the reject out of the MainLibraryFunction. Because otherwise I need to implement the handling of error case for each of the libraryfunctions. Because each of them will get the promise as argument, I would need to check in each of the functions, that did I get resolved or rejected promise as paramater. Then I would need to pass that rejected parameter through all the functions until the last function could then return it out of the MainLibraryFunction. This wouldn't be wise.

So what would be the best practise handling this? Should I add catch in the end of the chain? I heard if I add a catch to the end, it should break the chain even if any of them will reject. Then from the catch, I could return Promise.reject() out of the MainLibraryFunction.


The .then method accepts two arguments: onFulfilled and onRejected. If you do not supply an onRejected callback, this particular .then will not be invoked and the chain will fall through to the next handler that implements onRejected or .catch.

    .then(() => console.log('onFulfilled 1'))
    .catch(() => console.log('catch 1'));  // will get called

        () => console.log('onFulfilled 2'),
        () => console.log('onRejected 2')  // will get called
    .catch(() => console.log('catch 2'));  // will not get called

As such, no, you won't have to make each function parse their arguments. secondLibraryFn etc. will not be called if a promise gets rejected, because they're only defined as the onFulfilled handlers. You can safely assume they will be skipped and just add a .catch at the end of the chain where you want to catch any and all errors.