Javascript 将UI动画与异步请求相结合的最佳实践?

Javascript 将UI动画与异步请求相结合的最佳实践?,javascript,user-interface,animation,Javascript,User Interface,Animation,我正在构建一个老虎机游戏,UI动画一开始很容易实现,但当我必须从后端服务获取结果时,我发现很难将它与异步请求结合起来 假设我有一个老虎机模块,我可以这样使用: 从“./slot machine”导入SlotMachine; 常数sm=新SlotMachine(); document.querySelector(“#按钮”).addEventListener('click',()=>{ //持续运行5秒,结果显示为[1,2,3] 山猫({ 持续时间:5000, 结果:[1,2,3] }); });

我正在构建一个老虎机游戏,UI动画一开始很容易实现,但当我必须从后端服务获取结果时,我发现很难将它与异步请求结合起来

假设我有一个老虎机模块,我可以这样使用:

从“./slot machine”导入SlotMachine;
常数sm=新SlotMachine();
document.querySelector(“#按钮”).addEventListener('click',()=>{
//持续运行5秒,结果显示为[1,2,3]
山猫({
持续时间:5000,
结果:[1,2,3]
});
});
到目前为止还不错,但当我想从后端服务获取结果时,应该是这样的:

从“./slot machine”导入SlotMachine;
常数sm=新SlotMachine();
document.querySelector(“#按钮”).addEventListener('click',()=>{
获取('/api/getResult')。然后((结果)=>{
山猫({
持续时间:5000,
结果:结果
});
});
});
但是在这个实现中,用户体验不是很好,用户单击按钮后,直到
fetch
请求完成,动画才开始,在缓慢的网络连接中更糟糕

因此,我必须更改我的
老虎机
api,如下所示:

从“./slot machine”导入SlotMachine;
常数sm=新SlotMachine();
document.querySelector(“#按钮”).addEventListener('click',()=>{
const fakeStartTime=Date.now();
sm.startFakeAnimation();
获取('/api/getResult')。然后((结果)=>{
sm.stopFakeAnimation();
const fakeEndTime=Date.now();
山猫({
持续时间:5000-(fakeEndTime-fakeStartTime),
结果:结果
});
});
});
这样,用户操作将立即得到响应,但是,我认为要实现
startFakeAnimation
stopFakeAnimation
,使其感觉与“真实”动画无缝衔接并不容易


对于这类问题有更好的解决方案吗?

使用一组动画处理程序IMHO更有意义:

  • startAnimation
  • endAnimationWithResult
  • 必须在固定时间(上例中为5秒)设置动画的问题在于,您永远不知道fetch调用需要多长时间。假设我们已经将“animateTo”调用拆分为两个调用(“start”和“endWithResult”),剩下的实现将相当简单:

    ...
    const startTime = Date.now()
    sm.startAnimation()
    
    const result = await fetch('/api/getResult')
    const endTime = Date.now()
    const delayTime = Math.max(5000 - (endTime - startTime), 0)  // Making sure we always spin for at least 5 sec
    await new Promise(resolve => setTimeout(resolve, delayTime)) // Add delay to make sure we sping for at least 5 sec
    
    sm.endAnimationWithResult(result)  // Stop spinning wheels and display the numbers
    ...
    
    这样,您就不必处理同步两个动画序列的问题,而且代码对单元测试更加友好。因为SlotMachine类已经实现了一个固定长度的动画,所以将其分成两个方法应该不是很困难


    希望有帮助

    你可以让常规动画无限大,这样它就可以处理更糟糕的情况,而不是试图通过假动画变得聪明。你可以有一个单独的计时器,如果你得到服务的响应,它总是在5秒后尝试结束动画,否则它可以继续动画。因此,只有网络连接/连接不良的问题才会经历不同的动画持续时间。