javascriptecmascript-2017

Does awaiting a non-Promise have any detectable effect?


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.


Solution

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

    The following outputs 1, 2, 3:

    console.log(1);
    
    (async function() {
      var x = await 5;
      console.log(3);
    })();
    
    console.log(2);

    With the await removed it's 1, 3, 2:

        console.log(1);
    
        (async function() {
          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).