22

I add a click event handler to an element

 $(".elem").click(function(){
       $.post("page.php".function(){
         //code1
      })
 })

And then I trigger a click event

$(".elem").click();
//code2

How can i make sure that code2 executes after code1 executes

Veltzer Doron
  • 934
  • 2
  • 10
  • 31
Jithin Jose
  • 1,761
  • 2
  • 19
  • 35
  • Please define what you mean by "code 1 executes". Your code has an ajax method. So do you mean when ajax call executes or ajax executes and completes as well? – Rahatur Mar 02 '18 at 06:26

4 Answers4

17

(Ignoring WebWorkers) JavaScript runs on a single thread, so you can be sure that code2 will always execute after code1.

Unless your code1 does something asynchronous like an Ajax call or a setTimeout(), in which case the triggered click handler will complete, then code2 will execute, then (eventually) the callback from the Ajax call (or setTimeout(), or whatever) will run.

EDIT: For your updated question, code2 will always execute before code1, because as I said above an async Ajax callback will happen later (even if the Ajax response is very fast, it won't call the callback until the current JS finishes).

"How i make sure that code2 executes after code1 executes"

Using .click() with no params is a shortcut to .trigger("click"), but if you actually call .trigger() explicitly you can provide additional parameters that will be passed to the handler, which lets you do this:

$(".elem").click(function(e, callback) {
    $.post("page.php".function(){
      //code1

      if (typeof callback === "function")
         callback();
   });
});

$(".elem").trigger("click", function() {
    // code 2 here
});

That is, within the click handler test whether a function has been passed in the callback parameter and if so call it. This means when the event occurs "naturally" there will be no callback, but when you trigger it programmatically and pass a function then that function will be executed. (Note that the parameter you pass with .trigger() doesn't have to be a function, it can be any type of data and you can pass more than one parameter, but for this purpose we want a function. See the .trigger() doco for more info.)

Demo: http://jsfiddle.net/nnnnnn/ZbRJ7/1/

nnnnnn
  • 147,572
  • 30
  • 200
  • 241
  • 3
    I don't think that's true. They won't execute at the same time, but I don't believe that that the DOM API gives any guarantees about the order in which event handlers will be invoked. Even if they happen to fire in the right order on one version of one browser, that's no guarantee of what will happen in other cases. – Steve Jorgensen Aug 03 '12 at 06:17
  • People, there's only one event handler in the OP's question. code2 just triggers it. – JJJ Aug 03 '12 at 06:24
  • 1
    @SteveJorgensen the order of firing the handlers is not important here. OP's question is in regards to code that is called after you fire the event on the target element manually. And that code will always be called after all event handlers are executed. – Strelok Aug 03 '12 at 06:25
  • @SteveJorgensen - Even if there were multiple event handlers on the same element/event, if bound with jQuery then jQuery ensures they are fired in the same order they are bound. – nnnnnn Aug 03 '12 at 06:35
  • 1
    I was not aware that jQuery ensures event handlers are fired in the order they were bound, I would still not want to write code that depended upon that fact. It's not obvious behavior, and it would be too easy to break the code later by changing the binding order, not realizing it mattered. – Steve Jorgensen Aug 03 '12 at 06:43
  • user1545385 - I've updated my answer with a solution for you. @SteveJorgensen - I don't often write code with multiple handlers that must be fired in a particular order, but on those rare occasions that I do I make sure that _all_ such handlers have comments pointing this out... – nnnnnn Aug 03 '12 at 06:55
3

You can try writing this way:

 $(".elem").live("click", function(){
  //code1
 })

 // for newer jquery version from 1.9
 $(".elem").on("click", function(){
  //code1
 })

And, your trigger will always execute as fired.

Sudhir G
  • 381
  • 4
  • 7
SHAKIR SHABBIR
  • 1,295
  • 1
  • 14
  • 25
2

Wrap code2 in method and add it as a callback inside code1 so it will always get called after code1 executes

code2 = function(){/*code2*/};
$(".elem").click(function(){
  //code1
  code2();
 })
Gautam
  • 7,868
  • 12
  • 64
  • 105
  • that's not a solution;i want to execute click event in some other places without code2 – Jithin Jose Aug 03 '12 at 06:29
  • 2
    You never mentioned that it should be reusable. The above looks like a good solution to me. – Jonas Geiregat Aug 03 '12 at 06:32
  • 1
    You never said anything about that So I assumed. I should probably downvote the question for not being clear , But I am not going to do that since you are new. @JonasGeiregat: Thanks . – Gautam Aug 03 '12 at 06:38
-2

Javascript execution is line by line. So whatever comes up, will be executed first. So adding the click code before the other method will work.

Plus if there is any async call, then take a flag which is set only when you get response.

var clicked = false; $('#elem').click(function(){ // do some async process clicked = true; });

while (!clicked){ // do nothing }

// other function to be called

Or the second option will be, if using post method, set async = true in property.

Ankit
  • 6,388
  • 8
  • 54
  • 79