Как обрабатывать асинхронно в двух отдельных файлах? - PullRequest
0 голосов
/ 28 января 2019

У меня сейчас два файла.

  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.all и await, но я не могу найти способКак я мог применить их, не имея код в одном файле.

Ответы [ 2 ]

0 голосов
/ 28 января 2019

Вы хотите сохранить обещание, указывающее результат 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

Назовите глобальную переменную соответствующим образом (или даже используйте подходящую систему модулей, чтобы избежать глобальных переменных и получить декларативные зависимости), и, если возможно, разрешите обещание со значением, которое фактически ожидает анимация.

0 голосов
/ 28 января 2019

Вы можете 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
  });

Но это загрязняет глобальный охват.

...