title: Using for await...of with synchronous iterables
body: <p>MDN <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for-await...of" rel="noreferrer">says</a> <code>for await...of</code> has two use-cases:</p>
  
  <blockquote>
    <p>The <code>for await...of</code> statement creates a loop iterating over async
    iterable objects as well as on sync iterables,...</p>
  </blockquote>
  
  <p>I was previously aware of the former: async iterables using <code>Symbol.asyncIterator</code>. But I am now interested in the latter: synchronous iterables.</p>
  
  <p>The following code iterates over a synchronous iterable - an array of promises. It appears to block progess on the fulfilment of each promise.</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>async function asyncFunction() {
      try {
          const happy = new Promise((resolve)=&gt;setTimeout(()=&gt;resolve('happy'), 1000))
          const sad = new Promise((_,reject)=&gt;setTimeout(()=&gt;reject('sad')))
          const promises = [happy, sad]
          for await(const item of promises) {
              console.log(item)
          }
      } catch (err) {
          console.log(`an error occurred:`, err)
      }
  }
  
  asyncFunction() // "happy, an error occurred: sad" (printed in quick succession, after about 5 seconds)</code></pre>
  </div>
  </div>
  </p>
  
  <p>The behavior appears to be akin to awaiting each promise in-turn, per the logic shown below. Is this assertion correct?</p>
  
  <p><div class="snippet" data-lang="js" data-hide="true" data-console="true" data-babel="false">
  <div class="snippet-code snippet-currently-hidden">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>async function asyncFunction() {
      try {
          const happy = new Promise((resolve)=&gt;setTimeout(()=&gt;resolve('happy'), 1000))
          const sad = new Promise((_,reject)=&gt;setTimeout(()=&gt;reject('sad')))
          const promises = [happy, sad]
          for(let p of promises) {
              const item = await p
              console.log(item)
          }
      } catch (err) {
          console.log(`an error occurred:`, err)
      }
  }
  
  asyncFunction() // "happy, an error occurred: sad" (printed in quick succession, after about 5 seconds)</code></pre>
  </div>
  </div>
  </p>
  
  <p>I ask because this pattern of code has an implicit rejection wire-up pitfall that <code>Promise.all</code> and <code>Promise.allSettled</code> avoid, and it seems strange to me that this pattern would be explicitly supported by the language.</p>
  
  <p><div class="snippet" data-lang="js" data-hide="true" data-console="true" data-babel="false">
  <div class="snippet-code snippet-currently-hidden">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>window.addEventListener('unhandledrejection', () =&gt; {
    console.log('unhandled rejection; `sad` was not being awaited at the time it rejected')
  })
  
  async function asyncFunction() {
      try {
          const happy = new Promise((resolve)=&gt;setTimeout(()=&gt;resolve('success'), 1000))
          const sad = new Promise((_,reject)=&gt;setTimeout(()=&gt;reject('failure')))
          const promises = [happy, sad]
          for(let p of promises) {
              const item = await p
              console.log(item)
          }
      } catch (err) {
          console.log(`an error occurred:`, err)
      }
  }
  
  asyncFunction() // "unhandled rejection; `sad` was not being awaited at the time it rejected" (after about zero seconds), and then "happy, an error occurred: sad" (printed in quick succession, after about 5 seconds)</code></pre>
  </div>
  </div>
  </p>