Should you care about the settlement of Promise(s) or use Promise.finally() – [Everyday code]

This article is part of the series – [Everyday code]

– This logic should not be in Promise#finally()?

– Why? We just care that the Promise is settled.

– No. We care why it is settled.

TL; DR;

You might be tempted to put some specs logic in Promise#finally(), but here is why you should not do it.

It’s like try/catch/finally

In Instruction Steps Framework we try to load the list of parts in the instructions. There could be no list of parts in the instructions. How should we test this?

Consider the examples:

it("shows message 'No parts list provided' when there is no parts list", function() {
      // get the promise that the part list will be loaded, 
      // but we know that it will not be loaded, 
      // because this is how we setup the test. 
      this.promise = ... 

      // Using then()
      this.promise.then(() => {
              expect($("#partsList").text()).toContain("No parts list provided");
              done();
            });

      // Using catch()
      this.promise.catch(() => {
              expect($("#partsList").text()).toContain("No parts list provided");
              done();
            });

      // Using finally()
      this.promise.finally(() => {
              expect($("#partsList").text()).toContain("No parts list provided");
              done();
            });
    })
    

Would you use then(), catch() or finally() in the spec?

Using then()

The purpose of the promise is to load a file. The file is not there. So it is not successfully settled. As this is not successfully settled then() should not be called.

Using catch()

The promise is promising us that it will load a file and show something on the screen. It fails. It settles, but fails. It would be best to put the spec in catch().

Using finally()

The promise fails as the test is setup like this. We’ve setup the test to have the wrong url. But this is only in this test. What if other clients are waiting on the same promise in a production code. Should they use finally()?

From the finally documentation – https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/finally

The finally() method can be useful if you want to do some processing or cleanup once the promise is settled, regardless of its outcome.

The key here is “regardless of its outcome”. We get a Promise that is promising us to load a file. It fails. We care about the outcome. We care to have a successfully loaded list of parts, and if there is an ‘exceptional case’ we should catch() it and process it. We know exactly why the promise settles. We care.