title: Make Canvas Animation Asynchronous
body: <p>The following code is part of a bigger project:</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-html lang-html prettyprint-override"><code>&lt;body&gt;
    &lt;canvas id="check" width="35px" height="40px" style="background-color: blue;"&gt;&lt;/canvas&gt;
  &lt;/body&gt;
  &lt;script&gt;
    const check = document.getElementById('check');
    const checkCtx = check.getContext('2d');
    check.onclick = function() {
      drawCheck(checkCtx, 5, 30);
      setTimeout(function() {
        fadeOut(check);
      }, 1000);
      setTimeout(function() {
        check.style.opacity = "1";
        checkCtx.clearRect(0, 0, check.width, check.height);
      }, 2000);
      check.style.backgroundColor = "blue";
    }
  
    function drawCheck(ctx, x, y) {
      var x1 = x;
      var y1 = y;
      var x2 = x1;
      var y2 = y1;
      var x3 = x1 + 14;
      var y3 = y1 + 7;
      ctx.beginPath();
      ctx.strokeStyle = "green";
      ctx.lineCap = "round";
      ctx.lineWidth = 5;
      ctx.moveTo(x1, y1);
  
      function draw() {
        x2++;
        y2 += .5;
        ctx.lineTo(x2, y2);
        ctx.stroke();
        if (x2 &lt; x1 + 14) {
          requestAnimationFrame(draw);
        } else {
          function drawNext() {
            x3 += .5;
            y3 -= 1.5;
            ctx.lineTo(x3, y3);
            ctx.stroke();
            if (x3 &lt; x1 + 24) {
              requestAnimationFrame(drawNext);
            } else {
              return;
            }
          }
          drawNext();
          return;
        }
      }
      draw();
    }
  
    function fadeOut(obj) {
      var opc = 1;
      var finish = false;
      obj.style.opacity = 1;
  
      function fade() {
        opc -= 0.125;
        obj.style.opacity = opc + "";
        console.log(opc);
        if (opc &gt; 0) {
          requestAnimationFrame(fade);
        }
      }
      console.log("Wait for it...");
      fade();
      console.log("Finished!");
    }
  &lt;/script&gt;</code></pre>
  </div>
  </div>
  </p>
  
  <p>If you look at the console, you can see that the <code>fadeOut</code> function is ending before the <code>fade</code> function has ended. Because of this, I have to use multiple <code>setTimeout</code> functions. My other functions have the same problem. I don't want to have to rely on these, so how can I make the code wait until the called function has returned?</p>