如何在两个单独的文件中处理异步?

时间:2019-01-27 22:21:55

标签: javascript asynchronous include static-linking

我目前有两个文件。

  1. delay.js :为了简化示例的演示目的,假设文件包含一个异步函数。 (显然,实际文件要复杂得多)

    var delay = (ms) => (new Promise(res => setTimeout(res, ms)));
    
    delay(4000)
       .then( () => console.log('delay.js has finished');
    
  2. gravity.js :一个简单的画布游乐场:

// 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>


  

现在我要实现的目标:
  要以某种方式将这两个文件链接在一起,基本上delay.js完成后,gravity.js   应该开枪。

是否有一种方法可以某种方式应用.then( () => animate()),而无需将gravity.js代码复制粘贴到delay.js中? -基本上我希望将两个文件分开


我知道Promise.allawait命令,但是我想不通一种方法,如何在不将代码存储在单个文件中的情况下应用它们。

2 个答案:

答案 0 :(得分:1)

您将希望将表示delay.js的结果的承诺存储在全局变量中:

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

然后您可以在其他文件中使用它:

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

适当地命名全局变量(或者甚至使用适当的模块系统来避免全局变量并获得声明性依赖),并在可能的情况下使用动画实际上正在等待的值来解析promise。

答案 1 :(得分:0)

您可以让gravity.js监听window上的事件,并仅在该事件触发时激活其代码。 delay完成后,触发该事件,以便gravity.js看到并开始运行。

console.log('start');

// delay.js
var delay = (ms) => (new Promise(res => setTimeout(res, ms)));
delay(1000)
  .then(() => {
    console.log('delay.js has finished');
    window.dispatchEvent(new Event('delayDone'));
  });
  
// gravity.js
window.addEventListener('delayDone', () => {
  console.log('running gravity code');
  // insert gravity code here
});

事件和侦听器不是必需的 -另一种可能性是将Promise放在可全局访问的对象上,并gravity.js调用.then它:

console.log('start');

// delay.js
var delay = (ms) => (new Promise(res => setTimeout(res, ms)));
window.delayProm = delay(1000)
  .then(() => {
    console.log('delay.js has finished');
  });
  
// gravity.js
window.delayProm
  .then(() => {
    console.log('running gravity code');
    // insert gravity code here
  });

但这会污染全球范围。