1

This is how I understand the promise syntax to work:

promise.then((value) => {
    // handle async return
}, (error) => {
    console.log(error);
});

The promise can be fulfilled or rejected and you declare two closures separated by a comma where the first one handles success and the second handles failure. But all or most of the code I see doesn't use this syntax; it uses catch.

promise.then((value) => {
    // handle async return
}).catch((error) => {
    console.log(error);
});

However, I've read that catch() itself creates a new promise. Is that true? Because, as far as I understand it, catch is supposed to be the final stop of a process when an error is thrown, or does it work differently in JavaScript?

lurning too koad
  • 2,698
  • 1
  • 17
  • 47
  • 2
    From [MDN](//developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise/catch): _“The `catch()` method returns a `Promise`”_. From [the spec](//tc39.es/ecma262/#sec-promise.prototype.catch): _“2. Return ? Invoke(promise, "then", « undefined, onRejected »).” → “3. Let C be ? SpeciesConstructor(promise, %Promise%).”_ So, yes, it creates another Promise. It also requires an extra event loop cycle, if I recall correctly. But the two code snippets are not equivalent. `.then(`…`).catch(`…`)` also catches errors in the `.then` callback, not only in case `promise` was rejected. – Sebastian Simon Nov 15 '21 at 00:25
  • You can also easily test this: `const a = promise.then(`…`); const b = a.catch(`…`);`. Then, `a !== b`. – Sebastian Simon Nov 15 '21 at 00:27
  • @SebastianSimon so the first example doesn't leave any loose ends open, correct? It handles the error correctly and no additional promises are created. – lurning too koad Nov 15 '21 at 00:29
  • 1
    @kidcoder Yes, `.then(…, …)` is the preferred (but relatively unknown) pattern to handle errors from `promise`. It does, of course, create one additional promise, and errors thrown from either of the two callbacks won't be handled (which is often desirable). – Bergi Nov 15 '21 at 00:33
  • 1
    @kidcoder In contrast, `.then(…).catch(…)`, creates two additional promises, and errors thrown from the first callback will be handled by the second (so it can happen that both are called). – Bergi Nov 15 '21 at 00:35
  • @Bergi you say that `.then(…, …)` creates an additional promise. Don't you mean that it *could* create an additional promise if there is something performed within it that is asynchronous or could throw an error? If all we do is print to console in these handlers then there are no additional promises, correct? – lurning too koad Nov 15 '21 at 00:44
  • 1
    @kidcoder Any `.then()` and `.catch()` call *always* returns a new promise. At the end of a chain, that promise might be discarded, but `.then()` doesn't know that. And certainly it cannot depend on what the handler function will do in the future, which is unknown at the time when `.then()` is called. – Bergi Nov 15 '21 at 00:46
  • @Bergi maybe if you look at my code I will understand it better. This function has to either return a promise or `null` to terminate the function. I return the promise in line `47` but there is one additional promise in the outer scope called `getDocument` at line `15`. I handle the error of that promise at line `62`. As far as I understand it, I've covered all my bases, correct? There is no unaccounted for promise here that could prevent this function from terminating, is there? http://pastie.org/p/6322DdQGLUETyJ76ZqcxjP – lurning too koad Nov 15 '21 at 00:57
  • @kidcoder It's unclear what you mean by "*prevent this function from terminating*". The function always returns a promise, that promise always settles. It may fulfill or reject, both of which are fine; the function terminates and firebase returns a "*500 Internal Server Error, with an error code of `INTERNAL`*" on rejection according to the documentation. This may actually be more appropriate than `return null`, I don't know about your use case? And notice that the `admin.messaging().send(message)` still might return a promise that will reject, you are currently not handling those errors. – Bergi Nov 15 '21 at 01:07
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/239219/discussion-between-kidcoder-and-bergi). – lurning too koad Nov 15 '21 at 01:24

1 Answers1

-2

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/catch

YES.

p1.then(function(value) {
  console.log(value); // "Success!"
  throw new Error('oh, no!');
}).catch(function(e) {
  console.error(e.message); // "oh, no!"
}).then(function(){
  console.log('after a catch the chain is restored');
}, function () {
  console.log('Not fired due to the catch');
});

The return value of catch is thenable.

banyudu
  • 1,046
  • 9
  • 19