title: While loop inside async function executes one extra time when condition is false
body: <p>I'm using Electron to package an R Shiny app. It works fine in my computer and in most computers I've tested. However, in some cases it crashed (usually in slower computers). I'm not familiar with Javascript and I'm trying to understand what is happening in the JS code I'm using.</p>
  <p>After a while trying to figue out what caused the crash, I noticed that a while loop that should be executed <strong>only when my app hasn't been shown yet</strong>, is actually executed one more time. I suspect this may be causing the problem (although I'm not sure). The following is what I run when the electron app is ready.</p>
  <pre class="lang-js prettyprint-override"><code>
  app.on('ready', async () =&gt; {
    let shinyRunning = false
    let i = 1
  
    loadingSplashScreen = createSplashScreen('loading')
    mainWindow = createWindow()
  
    try {
      rShinyProcess = execa(NODER,
        ['-e', 'rbingo::launch_app(options = list(port = ' + srv.address().port + '))'], {
        env: {
          // Necessary for letting R know where it is and ensure we're not using another R
          'WITHIN_ELECTRON': 'T', // can be used within an app to implement specific behaviour
          'RHOME': rResources,
          'R_HOME_DIR': rResources,
          'R_LIBS': path.join(rResources, &quot;library&quot;),
          'R_LIBS_USER': path.join(rResources, &quot;library&quot;),
          'R_LIBS_SITE': path.join(rResources, &quot;library&quot;),
          'R_LIB_PATHS': path.join(rResources, &quot;library&quot;)
          }
        })
      } catch {
         console.log(new Date().toISOString() + ':rshinyprocess execa catched')
         console.log(e)
      }
      
      mainWindow.loadURL('http://127.0.0.1:' + srv.address().port);
      
      try {
          while(!shinyRunning) {
              const wait_res = await waitFor(1000);
              console.log(new Date().toISOString() + ': Trying to connect...' + i)
              i += 1
              console.log('shinyRunning status: ' + shinyRunning)
              
              mainWindow.webContents.executeJavaScript('window.Shiny.shinyapp.isConnected()', true)
                .then((result) =&gt; {
                      shinyRunning = true
                      mainWindow.show()
                      loadingSplashScreen.hide()
                      loadingSplashScreen.close()
                      console.log(new Date().toISOString() + ': Successfully connected to the app')
              })
                .catch((result) =&gt; {
              })
          }
      } catch (e) {
          console.log(new Date().toISOString() + ': Error catched while trying to load the app.')
      }
  
      // Emitted when the window is closed.
      mainWindow.on('closed', function () {
          console.log(new Date().toISOString() + ': mainWindow.closed()')
          cleanUpApplication()
      })
  
      mainWindow.webContents.on('did-fail-load', (event, code, desc, url, isMainFrame) =&gt; {
        console.log(new Date().toISOString() + ': DID FAIL LOAD - ', code, desc, url, isMainFrame);
      });
  })
  
  </code></pre>
  <pre><code>23:56:38.475 &gt; Application Started
  2020-11-06T02:56:38.489Z: Listening on port 49271
  2020-11-06T02:56:39.593Z: Trying to connect...1
  shinyRunning status: false
  2020-11-06T02:56:40.594Z: Trying to connect...2
  shinyRunning status: false
  2020-11-06T02:56:41.594Z: Trying to connect...3
  shinyRunning status: false
  2020-11-06T02:56:42.594Z: Trying to connect...4
  shinyRunning status: false
  2020-11-06T02:56:42.949Z: Successfully connected to the app 
  2020-11-06T02:56:43.594Z: Trying to connect...5             &lt;------ THIS SHOULDN'T BE HERE
  shinyRunning status: true                                   &lt;------ THIS SHOULDN'T BE HERE
  </code></pre>
  <p><strong>My question is:</strong> What is causing this while loop to be executed one extra time when <code>shinyRunning</code> is <code>true</code>?</p>
  <p>If you need more info about my app or the entire .js file, I can share it too.</p>
  <p>Thanks,
  Tomas</p>
  <p><strong>PS:</strong> <code>waitFor</code> is just</p>
  <pre class="lang-js prettyprint-override"><code>function waitFor(miliseconds) {
    return new Promise(resolve =&gt; {
      setTimeout(() =&gt; {
        resolve('resolved');
      }, miliseconds);
    });
  }
  </code></pre>
  <p><strong>EDIT:</strong></p>
  <p>Thanks to @cuspymd for the answer and @syarul for the comment.</p>
  <p>I've updated the code, now I'm not using a while loop anymore, and the console looks better.</p>
  <pre class="lang-js prettyprint-override"><code>
  ...
  
      mainWindow.loadURL('http://127.0.0.1:' + srv.address().port);
      
      try {
          await mainWindow.webContents.executeJavaScript('window.Shiny.shinyapp.isConnected()', true)
              .then((result) =&gt; {
                  mainWindow.show()
                  loadingSplashScreen.hide()
                  loadingSplashScreen.close()
                  console.log(new Date().toISOString() + ': Successfully connected to the app')
                  shinyRunning = true
          })
              .catch((result) =&gt; {
          })  
          
      } catch (e) {
          console.log(new Date().toISOString() + ': Error catched while trying to load the app.')
      }
  
  ...
  
  </code></pre>
  <pre><code>11:02:51.653 &gt; Application Started
  2020-11-06T14:02:51.668Z: Listening on port 63065
  2020-11-06T14:02:56.079Z: Successfully connected to the app
  </code></pre>