1

I have this one line of code but I cant seem to understand how this works

let p1 = p.then(a => [p1])
let [p2] = await p1
console.log(p1===p2)

I cant understand the first line. how can then get a hold of p1. afaik, a => [p1] inside then is executed immediately, but at the time of execution ,surely p1 was not formed yet. so, how come that code work? not only that, it somehow manages to correctly refer to itself. can anybody help understand what's going on here?

thanks

Das Raf
  • 55
  • 6
  • Good question, awful code. If you know who wrote it, they need a good talking to about readability – Phil Feb 02 '23 at 23:39
  • @pilchard wait, what? `p` can change it assignment to p1? – Das Raf Feb 02 '23 at 23:51
  • _“`a => [p1]` inside `then` is executed immediately”_ — From [my comment on your earlier question](/questions/75278134/why-we-cannot-refer-own-self-in-promise#comment132834773_75278134): _“Also, consider `const p1 = Promise.resolve().then(() => { console.log(p1); return "whatever"; });`, which **requires one pass through the job queue, before calling the `then` callback**.”_. – Sebastian Simon Feb 03 '23 at 00:14

1 Answers1

4

a => [p1] inside then is executed immediately

No, it's not. A .then called on a fulfilled Promise does not get called immediately. p1 is initialized and the Promise is assigned to it before the .then callback runs, so there's no problem.

This should make it clearer:

(async () => {
  const p = Promise.resolve();
  console.log('starting');
  let p1 = p.then(a => {
    console.log('then running');
    return [p1];
  });
  console.log('p1 has now been initialized');
  let [p2] = await p1;
  console.log(p1===p2);
})();

If it was executed immediately, you'd be correct - p1 hasn't been initialized yet at the point that it's being referenced, and an error would be thrown.

(async () => {
  const someObjectWhoseThenRunsImmediately = {
    then: (callback) => {
      // do something with callback, synchronously...
      callback();
    }
  };
  console.log('starting');
  let p1 = someObjectWhoseThenRunsImmediately.then(a => {
    console.log('then running');
    return [p1];
  });
  console.log('p1 has now been initialized');
  let [p2] = await p1;
  console.log(p1===p2);
})();

But that's not how Promises work.

CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
  • 1
    I don't get what you mean..? My purpose of putting it on the line right after `let p1` is to demonstrate that the log runs as soon as possible right after the `p1` variable gets fully initialized, and that the `.then` callback does not run first. – CertainPerformance Feb 02 '23 at 23:44