-2

I'm trying to understand Promises and their optional arguments.

(I'm assuming that because the arguments are optional, that too few are acceptable, and that too many arguments are also acceptable).

As an example:

let myPromise = new Promise(function(first, second, third) {
  let x = 0;
  if (x == 0) { //<<true
    second();
  } else {
    third();
  }
});

myPromise.then(
  function() {
    console.log("1");
  },
  function() {
    console.log("2");
  }
);

Runs the second function and outputs "2".

let myPromise = new Promise(function(first, second, third) {
  let x = 0;
  if (x != 0) { //<<false
    second();
  } else {
    third();
  }
});

myPromise.then(
  function() {
    console.log("1");
  },
  function() {
    console.log("2");
  }
);

Also runs the second function and outputs "2".

In the first case, is the Promise calling the function by name; And in the second case, calling the function by position?

How exactly does a Promise know which function to call?

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
Tom
  • 19
  • 5
  • ...what? In both cases the actual behaviour depends on the _position_ - the arguments to the executor are the function the resolves the promise and the function that rejects the promise, the arguments to the then callback are the function that's called on resolution and the function that's called on rejection, **in those orders**. What you name those things (if anything at all, they're anonymous in your second example) is irrelevant. It's just in one you explicitly reject the promise by calling the appropriate function, in the other you implicitly reject by trying to call `undefined`. – jonrsharpe Dec 09 '22 at 14:52
  • 1
    I suggest to start with a proper naming `first, second, third` -> should be `resolve, reject` that are for resolving and rejecting the promise. The `third` would be `undefined` causing type error. Throwing an error is equivalent to rejecting a promise. – Yury Tarabanko Dec 09 '22 at 14:54
  • 1
    The first case calls the `reject` function passed as the second argument to the executor, and the third case tries to call `undefined` as a function, which throws a type error and also rejects the promise, just for different reasons. – deceze Dec 09 '22 at 14:55

2 Answers2

1

The order of arguments matters because the order values are passed in determines which variables they are assigned to.

The callback to new Promise is given two arguments. A function to call to resolve the promise and a function to call to reject it. It doesn't get passed a third argument so third is undefined.

The then method takes two arguments. A function to call if the promise is resolved and a function to call if the promise is rejected.

In your second example, the promise is rejected. This isn't because you called the reject function, but because you attempted to call undefined as if it was a function causing an exception to be thrown.

const promise = new Promise((resolve, reject, third) => {
  console.log(typeof resolve);
  console.log(typeof reject);
  console.log(typeof third);
  third();
});

promise.then(
    (value) => console.log("Resolved", value),
    (error) => console.log("Rejected", error.message)
);
Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
0

The first argument to the constructor callback is the resolver function - call it, and it'll result in the returned Promise being fulfilled.

The second argument is a function that, if called, will result in the Promise rejecting.

The third (and all subsequent) arguments are undefined. You're free to define them when constructing a Promise, but their values will always be undefined.


In the first snippet, the second argument is called, rejecting the Promise.

In the second snippet, you call the third argument - but the third argument is not a function. A synchronous error thrown inside the Promise constructor results in the Promise rejecting. Check the error.message in the error handler for better understanding:

let myPromise = new Promise(function(first, second, third) {
  third();
});

myPromise.then(
  function() {
    console.log("1");
  },
  function(x) {
    console.log(x.message);
  }
);

So it's not that you're free to call whichever positional argument you wish, and the engine will magically understand what you were trying to do - it's that anything that results in an error being thrown will result in the Promise getting rejected, no matter the arguments.

CertainPerformance
  • 356,069
  • 52
  • 309
  • 320