Search code examples
javascriptasynchronousincludestatic-linking

How to handle asynchronny in two separate files?


I currently have two files.

  1. delay.js : For demonstration purposes to simplify the example, let's say the file contains a single asynchronous function. (Obviously actual file is much more complex)

    var delay = (ms) => (new Promise(res => setTimeout(res, ms)));
    
    delay(4000)
       .then( () => console.log('delay.js has finished');
    
  2. gravity.js: A simple canvas playground:

// Canvas settings:
const canvas = document.querySelector('canvas');
const c = canvas.getContext('2d');

canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

// in case somebody re-sizes the window
canvas.addEventListener("resize", function(){
  canvas.width = window.innerWidth;
  canvas.height = window.innerHeight;
});


function CanvasEl(x, y, v, width, height, f, g){
  this.x = x;
  this.y = y;
  this.v = v;

  this.draw = function(){
    c.fillRect(this.x, this.y, width, height);
  }

  this.gravitate = function(){

    if ( this.y + height >= window.innerHeight){
      this.v = -this.v;
      this.v = this.v * f;
    } else {
      this.v += g;
    }

    this.y += this.v;

    this.draw();
  }

}

var rect = new CanvasEl(0, 0, 2, window.innerWidth, 50, 0.76, 0.56);

function animate(){
  window.requestAnimationFrame(animate); // recursive (loop) for animation

  c.clearRect(0, 0, canvas.width, canvas.height);
  rect.gravitate();
}

animate();
<canvas></canvas>


Now what I want to achieve:
Is to somehow link these two files together, basically once delay.js finishes, only then gravity.js should fire.

Is there a way I could somehow apply .then( () => animate()), without having to copy-paste the gravity.js code into delay.js? -- basically I'd prefer to keep the two files separate


I am aware of Promise.all and await commands, but I can't figure out a way, how could I apply them without having the code in one single file.


Solution

  • You'll want to store the promise that indicates the result of delay.js in a global variable:

    // delay.js
    …
    var gravityResult = delay(4000)
       .then( () => console.log('delay.js has finished');
    

    Then you can use that in the other file:

    // gravity.js
    …
    gravityResult.then(animate); // instead of calling `animate()` right away
    

    Name the global variable appropriately (or even use a proper module system to avoid globals and get declarative dependencies), and if possible resolve the promise with the value that the animation is actually waiting for.