制作一个单击功能等待上一个通话结束
我正在与React合作,并且我有问题连续同步点击(ONCLICK EVENT):
我的按钮触发了一个调用两个函数的函数resetViews
and code> code> choce> carriceviews (> ChargeViews
需要时间),因此,当我快速单击两次时:
resetView
被罚款(它将views> views> views> views> views> views> current
null),- 然后
code> code> codeviews < /code>被调用,但是由于花费时间,因此不会在此之后更新
viewsref.current
。 - 因此
resetView
被调用,但是viewsRef.current
仍然是null(因为chode> charderviews
尚未对其进行更新),因此它无能为力, - 那么我获取两个延迟执行
curophiws
, - 因此两次单击后,我获得了1个执行
resetView
和两个延迟执行chode> carriceviews
我想要的是,我想要的是在单击,单击后,阻止所有内容(即使用户单击我们什么都不做),并执行resetView
然后code> chode> codeviews
,然后取消屏蔽以接收另一个单击并执行相同的工作。
<MyButton onClick={() => {
resetViews();
chargeViews();
}}>
Click me
</MyButton>
如果我单击得这么快,则需要时间的功能
const chargeViews = () => {
if(!viewsRef.current){
...
reader.setUrl(url).then(()=>{
reader.loadData().then(()=>{
...
viewsRef.current = reader.getData();
})})
}}
,该功能被忽略了(如果我单击并等待一点,则可以正常单击,然后再单击),但是如果我单击并再次单击快速单击,则它将被忽略。
const resetViews = () => {
if (viewsRef.current){
...
viewsRef.current = null;
}}
I'm working with React, And I have a problem synchronizing clicks successively (onClick events):
My button triggers a function that calls two functions resetViews
and chargeViews
(chargeViews
takes time), so when I click two times rapidely:
resetView
is executed fine (it setsviewsRef.current
to null)- then
chargeViews
is called but as it is taking time it won't updateviewsRef.current
right after. - so
resetView
is called butviewsRef.current
is still null (becausechargeViews
doesn't update it yet) so it will do nothing, - then I get two delayed executions of
chargeViews
- so after two clicks I got 1 execution of
resetView
and two delayed executions ofchargeViews
What I want is after clicking, block everything (even if the user clicks we do nothing) and execute resetView
then chargeViews
and then unblock to receive another click and do the same work.
<MyButton onClick={() => {
resetViews();
chargeViews();
}}>
Click me
</MyButton>
The function that takes time
const chargeViews = () => {
if(!viewsRef.current){
...
reader.setUrl(url).then(()=>{
reader.loadData().then(()=>{
...
viewsRef.current = reader.getData();
})})
}}
The function that getting ignored if I click so fast, (It works fine if I click and I wait a little bit then I click again) but if I click and click again fast It is ignored.
const resetViews = () => {
if (viewsRef.current){
...
viewsRef.current = null;
}}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我不完全确定掌握整个问题......如果不需要这么长的文本,这将是一个评论。
无论如何,只要您需要在单击按钮后禁用该按钮,您应该在其 onclick 处理程序的开头处理它:
并在最后重置它:
一般来说,您所做的在调用许多函数方面是正确的在处理程序内的链中执行。但这两个函数似乎有一个承诺调用..在这种情况下,它们不会在链中执行,等待第一个函数完成。
因此,您应该将第二个调用作为第一个调用的回调传递,以便只有在第一个调用完成其工作后才有机会调用它。
我希望有人能直奔主题,建议如何使异步函数“等待”,以便无论它做什么,在调用时都会等待其完成,然后才能评估下一个语句。通常,只需在签名前添加
await
即可,但有一些注意事项。I'm not totally sure to grasp the whole issue... this would be a comment if it didn't require such a long text.
Anyway as far as you need to disable the button once it's clicked you should deal with it at the beginning of its onclick handler:
and reset it at the end:
In general what you did was correct in terms of calling a number of functions to be executed in chain inside the handler. But those 2 functions seem to have a promise invocation.. in that case those won't be executed in chain waiting for the first one to finish.
So you should pass the second invocation as a callback to the first, to have the chance to call it ONLY once the first one finished its job.
I hope someone will just go straight to the point suggesting how making an async function "await" so that whatever it does, when invocated it will be waited for to complete before the next statement is evaluated. Usually it's just a matter of adding
await
before its signature but there are some caveats.首先,您需要将您的承诺功能转换为异步功能,然后在调用它们时等待它们。
这将使控制执行顺序更加容易:
然后,您需要一个Isexecuting Ref,当其他援引执行时将是正确的,而当当前没有执行时,则需要false:
最后,使用新创建的
handleclick
在您的JSX中功能:First, you need to convert your Promise-utilizing functions into async functions and then await them when invoking them.
This will make it easier to control the order of execution:
Then, you need an isExecuting ref that will be true when other invokations are executing and false when none are currently executing:
Lastly, use the newly-created
handleClick
function in your JSX: