68

One can await a non-Promise and that's good so.

All these expressions are valid and cause no error:

await 5
await 'A'
await {}
await null
await undefined 

Is there any detectable effect of awaiting a non-Promise? Is there any difference in behavior one should be aware of to avoid a potential error? Any performance differences?

Are the following two lines completely same or do they theoretically differ?:

var x = 5
var x = await 5

How? Any example to demonstrate the difference?

PS: According TypeScript authors, there is a difference:

var x = await 5; is not the same as var x = 5;; var x = await 5; will assign x 5 in the next tern, where as var x = 5; will evaluate immediately.

ttulka
  • 8,535
  • 4
  • 36
  • 45

2 Answers2

80

await is not a no-op. If the awaited thing is not a promise, it is wrapped in a promise, that promise is awaited. Therefore await changes the execution order (but you should not rely on it nevertheless):

console.log(1);
(async function() {
  var x = await 5; // remove await to see 1,3,2
  console.log(3);
})();
console.log(2);

Additionally await does not only work on instanceof Promises but on every object with a .then method:

await { then(cb) { /* nowhere */ } };
console.log("will never happen");

Is there any detectable effect of awaiting a non-Promise?

Sure, .then gets called if it exists on the awaited thing.

Is there any difference in behavior one should be aware of to avoid a potential error?

Don't name a method "then" if you don't want it to be a Promise.

Any performance differences?

Sure, if you await things you will always defer the continuation to a microtask. But as always: You won't probably notice it (as a human observing the outcome).

Jonas Wilms
  • 120,546
  • 16
  • 121
  • 140
  • 1
    What do you mean by `no a no op` ? you mean `not a no-op` right ? – Kunal Mukherjee Mar 20 '19 at 14:24
  • 2
    @kunal yup, I type faster than my keyboard reacts, leading to some funny typos :) – Jonas Wilms Mar 20 '19 at 14:32
  • 2
    _"but you should not rely on it nevertheless"_ Why not? – a better oliver Apr 24 '19 at 19:09
  • 2
    @aBetterOliver example: you start two very short running actions and want to work with their result. You know that action 1 finsihes earlier than action 2, so you store the result of 1 in a variable, and access that when 2 is done. Now someone somewhen changes the algorithm, so that 1 is slower than 2. Your code breaks and no one knows why. If you have to execute async tasks in a specific order, you should write that down explicitly. – Jonas Wilms Apr 24 '19 at 19:14
19

Completely agreed with Jonas's statements. One thing that was not answered in his question was Are the following two lines completely same or do they theoretically differ?:

following two lines are not completely same, they're theoretically different.

  1. var x = 5
  2. var x = await 5

execution time in my console for 1st and 2nd statement is 0.008056640625ms and 0.055908203125ms respectively. async/await, setTimeOut etc are APIs provided by Run time in which JavaScript Run time is running. Putting await on a non-promise will be executed in event-loop. Line 1 will be executed right after reaching the stack but the line 2 will take few time(milliseconds) as it will 1st go to the stack and then to the task queue after skipping webAPI waiting section because there's no promise to be resolved & finally after that control will be given to stack again for execution.

fahad tufail
  • 437
  • 3
  • 10