制作一个单击功能等待上一个通话结束

发布于 2025-01-17 22:28:17 字数 1438 浏览 0 评论 0原文

我正在与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 sets viewsRef.current to null)
  • then chargeViews is called but as it is taking time it won't update viewsRef.current right after.
  • so resetView is called but viewsRef.current is still null (because chargeViews 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 of chargeViews

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

彻夜缠绵 2025-01-24 22:28:18

我不完全确定掌握整个问题......如果不需要这么长的文本,这将是一个评论。

无论如何,只要您需要在单击按钮后禁用该按钮,您应该在其 onclick 处理程序的开头处理它:

$(this.event.target).prop('disabled', true);

并在最后重置它:

$(this.event.target).prop('disabled', false);

一般来说,您所做的在调用许多函数方面是正确的在处理程序内的链中执行。但这两个函数似乎有一个承诺调用..在这种情况下,它们不会在链中执行,等待第一个函数完成。

因此,您应该将第二个调用作为第一个调用的回调传递,以便只有在第一个调用完成其工作后才有机会调用它。

我希望有人能直奔主题,建议如何使异步函数“等待”,以便无论它做什么,在调用时都会等待其完成,然后才能评估下一个语句。通常,只需在签名前添加 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:

$(this.event.target).prop('disabled', true);

and reset it at the end:

$(this.event.target).prop('disabled', false);

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.

顾北清歌寒 2025-01-24 22:28:18

首先,您需要将您的承诺功能转换为异步功能,然后在调用它们时等待它们。
这将使控制执行顺序更加容易:

const chargeViews = async () => {
  if(!viewsRef.current){
   ...
   await reader.setUrl(url);
   await reader.loadData();
   ...
   viewsRef.current = reader.getData();
  }
}

然后,您需要一个Isexecuting Ref,当其他援引执行时将是正确的,而当当前没有执行时,则需要false:

const isExecuting = useRef(false);

const handleClick = async () => {
  if (!isExecuting.current) {
    // block other clicks from performing actions in parallel
    isExecuting.current = true;
    try {
      resetViews();
      await chargeViews();
    } finally {
      // unblock other clicks
      isExecuting.current = false;
    }
  }
};

最后,使用新创建的handleclick在您的JSX中功能:

<MyButton onClick={handleClick}>
  Click me
</MyButton>

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:

const chargeViews = async () => {
  if(!viewsRef.current){
   ...
   await reader.setUrl(url);
   await reader.loadData();
   ...
   viewsRef.current = reader.getData();
  }
}

Then, you need an isExecuting ref that will be true when other invokations are executing and false when none are currently executing:

const isExecuting = useRef(false);

const handleClick = async () => {
  if (!isExecuting.current) {
    // block other clicks from performing actions in parallel
    isExecuting.current = true;
    try {
      resetViews();
      await chargeViews();
    } finally {
      // unblock other clicks
      isExecuting.current = false;
    }
  }
};

Lastly, use the newly-created handleClick function in your JSX:

<MyButton onClick={handleClick}>
  Click me
</MyButton>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文