我正在制作一个基于套接字连接的简单应用程序。基本上,一个用户决定其他用户可以看到什么。功能之一是为其他用户启动计时器。因此,有一个带有timerState变量和startTimer函数的Timer组件。当用户连接到套接字时,计时器组件与整个用户视图一起呈现。对传入事件“计时器已启动”做出反应非常简单并且工作完美。当计时器已经启动并且用户刷新浏览器时(或者在计时器已经设置时只是晚连接),问题就开始了。
计时器设置的信息存储在数据对象中,该数据对象在初始连接到套接字后作为欢迎事件发送给用户。
为了简化,用户视图的组成如下:
{#if !isDataComplete}
<WaitingComponent>
{:else}
<Timer bind:{tools}>
{/if}
Tools是一个对象,包含一些方法,主要是startTimer方法。
因此,连接后,用户接收数据对象,该数据对象将 wiev 从等待切换到应用程序 wiev(此处:计时器,最初为空,但已渲染)。如果有计时器属性,则意味着已经设置了计时器,并且应该调用 startTimer 方法。但是,startTimer 方法尚无法访问,因为脚本比渲染速度更快,并且计时器组件尚不存在。实际上并没有获取数据,它带有来自套接字的“欢迎”事件,因此等待数据并不能解决问题,我需要等待组件渲染。
let isDataComplete = false;
socket.on('welcome', async (incomingData) => {
isDataComplete = incomingData.isAppReady; // triggers switch view if true
await timeout(500); // my "lame solution" (timeout is just setTimeout wrapped in Promise to make that awaitable)
if (data.timer) {
const currTime = Date.now();
if (currTime < data.timer.start + data.timer.duration) {
const remainingTime = Math.floor(
(data.timer.start + data.timer.duration - currTime) /
1000
);
tools.startTimer(remainingTime, true);
}
}
});
正如您所看到的:我通过在脚本中添加等待 setTimeout 500 毫秒(在调用 startTimer 之前)“解决”了这一问题,这可以解决问题,组件可以渲染并且方法已经可以访问。但不知怎的,我觉得这是蹩脚的解决方案,所以也许有人可以通过其他方式提供帮助?
我只需将计时器组件放在 if 块之外,使其甚至在接收数据之前就进行渲染,但这并不是一个好主意,因为视图结构。
我试图将 setTimer 方法存储在其他地方并导入它,但这会导致从外部管理计时器状态时遇到一些困难。但这当然是一种有效的尝试方法。
多谢!
普热梅克