如何处理两个单独文件中的异步?
How to handle asynchronny in two separate files?
我目前有两个文件。
delay.js :为了简化示例的演示目的,假设文件包含一个异步函数。 (显然实际文件要复杂得多)
var delay = (ms) => (new Promise(res => setTimeout(res, ms)));
delay(4000)
.then( () => console.log('delay.js has finished');
gravity.js:一个简单的 canvas 游乐场:
// 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.
有没有什么方法可以应用 .then( () => animate())
,而不必将 gravity.js
代码复制粘贴到 delay.js
中? -- 基本上我更愿意将两个文件分开
我知道 Promise.all
和 await
命令,但我想不出办法,如果没有代码在一个文件中,我怎么能应用它们。
您可以让 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
});
但这会污染全局范围。
您需要将指示 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
适当地命名全局变量(或者甚至使用适当的模块系统来避免全局变量并获得声明性依赖),并且如果可能的话用动画实际等待的值解析承诺。
我目前有两个文件。
delay.js :为了简化示例的演示目的,假设文件包含一个异步函数。 (显然实际文件要复杂得多)
var delay = (ms) => (new Promise(res => setTimeout(res, ms))); delay(4000) .then( () => console.log('delay.js has finished');
gravity.js:一个简单的 canvas 游乐场:
// 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 oncedelay.js
finishes, only thengravity.js
should fire.
有没有什么方法可以应用 .then( () => animate())
,而不必将 gravity.js
代码复制粘贴到 delay.js
中? -- 基本上我更愿意将两个文件分开
我知道 Promise.all
和 await
命令,但我想不出办法,如果没有代码在一个文件中,我怎么能应用它们。
您可以让 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
});
但这会污染全局范围。
您需要将指示 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
适当地命名全局变量(或者甚至使用适当的模块系统来避免全局变量并获得声明性依赖),并且如果可能的话用动画实际等待的值解析承诺。