我正在构建一个老虎机游戏,一开始很容易实现UI动画,但是当我不得不从后端服务中获取结果时,我发现很难将它与异步请求结合起来。
想象我有一个老虎机模块,我可以这样使用:
import SlotMachine from './slot-machine';
const sm = new SlotMachine();
document.querySelector('#button').addEventListener('click', () => {
// keep running for 5 seconds and display result as [1, 2, 3]
sm.animateTo({
duration: 5000,
result: [1, 2, 3]
});
});
到目前为止还不错,但是当我想从后端服务中获取结果时,将是这样的:
import SlotMachine from './slot-machine';
const sm = new SlotMachine();
document.querySelector('#button').addEventListener('click', () => {
fetch('/api/getResult').then((result) => {
sm.animateTo({
duration: 5000,
result: result
});
});
});
但是此实现中的用户体验不是很好,在用户单击按钮后,动画直到fetch
请求完成后才开始播放,在网络连接缓慢的情况下更是如此。
所以我必须像这样更改我的slot-machine
api:
import SlotMachine from './slot-machine';
const sm = new SlotMachine();
document.querySelector('#button').addEventListener('click', () => {
const fakeStartTime = Date.now();
sm.startFakeAnimation();
fetch('/api/getResult').then((result) => {
sm.stopFakeAnimation();
const fakeEndTime = Date.now();
sm.animateTo({
duration: 5000 - (fakeEndTime - fakeStartTime),
result: result
});
});
});
这样,用户操作将立即获得响应,但是,我认为实施startFakeAnimation
和stopFakeAniamtion
并不容易,以使其与“真实”动画无缝融合
有没有更好的解决此类问题的方法?
答案 0 :(得分:0)
拥有一组动画处理程序恕我直言会更有意义:
必须设置固定时间的动画(在上面的示例中为5秒)的问题是,您永远不知道提取调用将花费多长时间。假设我们已将“ 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类已经实现了固定长度的动画,因此将其分为两种方法在IMO中并不难。
希望有帮助!