4

The following currently logs Yahtzee in node, chrome, firefox.

As you can see, not even prototype of Promise was set.

const fake = new Number(1)
fake.then = fn => setTimeout(fn, 0, 'Yahtzee')
const main = async () => {
  console.log(await fake)
}
main()

Does this works universally? And more importantly, will this behavior likely persist?

messerbill
  • 5,499
  • 1
  • 27
  • 38
Mihail Malostanidis
  • 2,686
  • 3
  • 22
  • 38
  • 2
    Yes, that's how it is supposed to work, and it's implemented like that by the spec which is unlikely to change. – Bergi Mar 03 '18 at 16:04
  • Technically, you can await any expression. `const main = async () => { console.log(await 3); }; main();` will log 3. Why would you want to? That's a different question. :) – Heretic Monkey Mar 03 '18 at 16:20
  • @MikeMcCaughan, please note that the result of the await becomes "Yahtzee" and not 1. – Mihail Malostanidis Mar 03 '18 at 20:03

1 Answers1

2

Yes, this will work. According to the specs, a new Promise will be called and resolve with that value. Promise.resolve works with thenable so it will work the same for await

So, the above is equivalent to

const fake = new Number(1)
fake.then = fn => setTimeout(fn, 0, 'Yahtzee')
const main = async () => {
  console.log(await Promise.resolve(fake))
}
main()

Where it is the .resolve() method that calls then on the object.

Mihail Malostanidis
  • 2,686
  • 3
  • 22
  • 38
Axnyff
  • 9,213
  • 4
  • 33
  • 37
  • I tentatively added ad edit, please tell me if it is correct. I tried to follow the spec, but I can't find where that is specified. Where in `PromiseResolve` does it happen? Is it the `Call(promiseCapability.[[Resolve]], undefined, « x »)`? If it is, then where in `NewPromiseCapability` does it check for the `then` method? – Mihail Malostanidis Mar 03 '18 at 20:22
  • https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/resolve The beginning is good for how thenable works with promises – Axnyff Mar 03 '18 at 21:13
  • Excellent! I was hoping to understand the spec for once, though. The Description is wrong :c It says it **returns a Promise that is resolved**. Not only is it not always a resolved promise, but it can even reject :v https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/resolve#Description – Mihail Malostanidis Mar 04 '18 at 15:07
  • @MihailMalostanidis Maybe you misunderstood [what `resolve` means](https://stackoverflow.com/a/41910860/1048572) – Bergi Mar 04 '18 at 21:07
  • @Bergi I doubt it, since I linked to the `Promise.resolve()` static method and not the first argument to the `executor` function. – Mihail Malostanidis Mar 04 '18 at 22:56
  • @MihailMalostanidis The question I linked *is* about `Promise.resolve`. And there is hardly any difference, given that `Promise.resolve = function(x) { return new this(resolve => resolve(x)); }` – Bergi Mar 04 '18 at 22:59