Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

272
Views
Make an onClick function wait the previous call to end

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;
}}
about 4 years ago · Juan Pablo Isaza
2 answers
Answer question

0

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.

about 4 years ago · Juan Pablo Isaza Report

0

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>
about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!