title: LONG: Why if we return a promise from our async function, its not immediately resolved?
body: <p><strong>Apologies in advance if this is a dumb question, I've been trying to find the answer to my question for a good while now but still no luck and that's causing me not to progress further in my JS learning!</strong></p>
  <p><strong>Q:</strong> Why even if we return a resolved promise from our async function, it's not immediately resolved?</p>
  <p>Now MDN is teaching me this:</p>
  <blockquote>
  <p>Async functions always return a promise. If the return value of an
  async function is not explicitly a promise, it will be implicitly
  wrapped in a promise.</p>
  </blockquote>
  <p>This means, both the functions below f1 and f2, are equivalent!</p>
  <pre><code>async function f1(){
      
      return 100;
  }
   
      async function f2(){
      
      return Promise.resolve(100);
  }
      
      console.log(f1());
      console.log(f2());
  </code></pre>
  <p>However, we get different logs:</p>
  <p>One logs: Promise {: 100}</p>
  <p>Second logs: Promise pending</p>
  <p>What's even more confusing is, when I expand the second promise's, even tho it says its pending, i see [[PromiseResult]]: 100.</p>
  <p>Now my naive programming experience suggests, only if a value (string, num, arr, obj etc) is returned from the async function, the promise our async function returns by default will be resolved to that value!</p>
  <p>But if our async function returns a promise that we ourself made inside our async function, then the default promise that async function  returns wont be returned, instead the promise we made inside our async function will be returned.</p>
  <p>But that raises another question, what if we have await in our function? Await immediately returns a pending promise and whatever value we return from our async function is resolved with the promise our async function returns but again, what if we're returning a function?</p>
  <p>A friend of mine told me if we are returning a resolved promise from our async function, some anonymous task is registered into the microtask queue which when run (after all the sync code,) unpacks the value from our the secondary promise and finally resolves our default promise returned by async function with that value and that seems to be working!</p>
  <p>To test this assumption, I wrote this code:</p>
  <pre><code>   let o = new Promise(function (r){
      r(100)
  });
  
  o.then(function first(){console.log(p)})
  .then(function second(){console.log(p)})
  
  async function f(){
  
  return new Promise(function (r){
      r(100)
  })
  }
  
  let p = f();
  </code></pre>
  <p>Our o promise is gonna be resolved immediately so our first .then cb will be pushed to the microtask queue, like this maybe!</p>
  <p>MICROTASK_QUEUE = [function first(){console.log(p)}]</p>
  <p>On the next line we run f(), it goes inside f and sees we're returning a resolved promise so it returns a pending promise into p!</p>
  <p>Now our microtask is like this:</p>
  <p>MICROTASK_QUEUE = [function first(){console.log(p)}, someTaskThatWillUnpackOurPromiseAndResolveOurPromiseReturnedByTheAsyncFunctionByThatValue]</p>
  <p>Our sync code is done, so we run our first task from microtask queue which happens to be our first .then, this one: function first(){console.log(p)}</p>
  <p>This one is run and as expected, prints pending! Since this returns nothing, it returns undefined but since the promise's root .then is resolved, now our microtask queue looks like this after registering another .then.</p>
  <p>MICROTASK_QUEUE = [someTaskThatWillUnpackOurPromiseAndResolveOurPromiseReturnedByTheAsyncFunctionByThatValue, function second(){console.log(p)}]</p>
  <p>Now, this function is run someTaskThatWillUnpackOurPromiseAndResolveOurPromiseReturnedByTheAsyncFunctionByThatValue() (maybe internally unlike our .then functions)</p>
  <p>now at this point promise that was earlier returned by our async function should be resolved with the value we resolved in our custom-made function, correct?</p>
  <p>Now finally event loop checks the microtask queue and finds the final function to run, this one:</p>
  <p>function second(){console.log(p)}</p>
  <p>now why does this still return a pending promise?</p>
  <p>I think there's still one more step I'm missing in this whole equation because if I put the 3rd .then, it finally logs this &quot;Promise {: 100}&quot; which is what I'm after!</p>
  <pre><code>let o = new Promise(function (r){
      r(100)
  });
  
  o.then(x =&gt; console.log(p))
  .then(x =&gt; console.log(p))
  .then(x =&gt; console.log(p))
  async function f(){
  
  return new Promise(function (r){
      r(100)
  })
  }
  
  let p = f();
  </code></pre>
  <p><strong>I'm thankful to you if you read this far and it'd be greatly appreciated if someone could answe this</strong></p>