-2

I have multiple jQuery click event handlers, each that run asynchronous code (i.e. AJAX call) when clicked.

I have some code like this:

$(selector1).click((e) => {
  asyncCode1();
)};
$(selector2).click((e) => {
  asyncCode2();
)};
$(selector3).click((e) => {
  asyncCode3();
)};

$(selector1).click(); // runs asyncCode1()
$(selector2).click(); // runs asyncCode2()
$(selector3).click(); // runs asyncCode3()

I want $(selector2).click() to run only after $(selector1).click() has completed execution, since asyncCode1() generates elements in the DOM that will eventually be selected in $(selector2).

Should I be returning promises on each of the click handlers? I'm not sure about best practices and how to go about doing this.

liphenste
  • 7
  • 2
  • 1
    You seem to be over-complicating this. If you use delegated event handlers then you don't need to worry about the order of sending the requests, or when the elements are created in the DOM as the event handlers are bound to a static parent and applied to children by proxy when they exist in the DOM. See [this question](https://stackoverflow.com/questions/203198/event-binding-on-dynamically-created-elements) for more details – Rory McCrossan Aug 13 '19 at 19:39
  • In my case, each of the selectors are already bound to static parent elements. I want to ensure that by the time the second click handler is called, it would include the child element that I generated in my first click handler – liphenste Aug 13 '19 at 19:58
  • Think: I want to dynamically generate a pop-up window, and then immediately after, minimize the window through 'clicking' a minimize button on this window – liphenste Aug 13 '19 at 19:59
  • That's a very odd thing to be doing then as it makes no sense. Why would you want to create a pop-up which you immediately hide? This all sounds like an X/Y question where you're asking about a solution you've come up with instead of telling us what the actual problem you're trying to solve is, as I'm 99% sure there will be a better way to do whatever it is you need. – Rory McCrossan Aug 13 '19 at 20:00
  • Return promises and then run the dependent code in the `.then()` callback. – Barmar Aug 13 '19 at 20:22
  • If your click handlers returned promises, you could use .triggerHandler to gain access to said promises and wait on them. – Kevin B Aug 13 '19 at 20:24

1 Answers1

-1

Yes, you can do it with Promise. Like this:

let asyncCode1Promise;

$(selector1).click((e) => {
    asyncCode1Promise = asyncCode1(); // no await here!
)};
$(selector2).click(async (e) => {
    await asyncCode1Promise;
    asyncCode2();
)};

async asyncCode1() {
    ...
}
...

In that case, clicking selector2 will wait for completing code1 (if it's not complete yet). And if it was complete before clicking selector2, then asyncCode2 will run without any delay.

The good thing about using promises is that you can click selector2 multiple times, and it will work as expected (all clicks which are done before completion asyncCode1 will wait for its completion, and all clicks after asyncCode1 finished will call asyncCode2 immediately).

Maxím G.
  • 860
  • 10
  • 14