A brief look at async-await
<p><pre><code>  check()
    .then(result =&gt; {
      if (result) {
         &#x2F;&#x2F; set state to finished
      }
      check()
        .then(result =&gt; {
          if (result) {
              &#x2F;&#x2F; set state to finished
          }
          check()
            .then(result =&gt; {
              if (result) {
                 &#x2F;&#x2F; set state to finished
              }
              check()
                .then(result =&gt; {
                  if (result) {
                    &#x2F;&#x2F; set state to finished
                  }
                  check()
                    .then(result =&gt; {
                      if (result) {
                         &#x2F;&#x2F; set state to finished
                      }

                      &#x2F;&#x2F; set state to not done
                    })
                    .catch(error =&gt;  &#x2F;&#x2F; set state to failed);
                })
                .catch(error =&gt;  &#x2F;&#x2F; set state to failed);
            })
            .catch(error =&gt;  &#x2F;&#x2F; set state to failed);
        })
        .catch(error =&gt;  &#x2F;&#x2F; set state to failed);
    })
    .catch(error =&gt;  &#x2F;&#x2F; set state to failed);

</code></pre>
For the love of everything that’s sacred, please don’t do this. The strength of promises is that they can free us from that exact kind of callback hell, and they do that by being chainable.<p><pre><code>  const resultOrNull = await Promise.resolve(null).
       then(result =&gt; result || check()).
       then(result =&gt; result || check()).
       then(result =&gt; result || check()).
       then(result =&gt; result || check()).
       then(result =&gt; result || check()).
       catch(error =&gt; null);
</code></pre>
Calling .then&#x2F;.catch inside of a .then&#x2F;.catch is a huge red flag. Almost always, you want to return the promise and chain instead.