views:

68

answers:

4

My gut tells me that if i am on a laggy server and the user fires two events fast enough on the success function c will be the value of the most recent event causing func1 to use the wrong value. <--- This is a guess, i haven't proved it. Its a feeling.

How do i ensure that i use the right value when calling func1? I prefer not to send c to the server and i dont know if or how to serialize the data and deserialize it back. How do i make this code safe?

$('.blah').click(function (event) {
    var c = $(this).closest('.comment');
    ...
    $.ajax({ url: "/u", type: "POST", dataType: "json", data: { ... },
        success: function (data) {
            func1(c. data.blah);//here
A: 

I guess the easiest way to accomplish this is calling

var $this = $(this);
$this.attr('disabled', 'disabled');

before var c = $(this).closest...

to re-enable .blah add the 'complete' event handler into your .ajax request.

complete: function(xhr, status){
   $this.removeAttr('disabled');
}

This will only work if .blah is an input element. If not, you may unbind/bind the click event instead of disabling the element

jAndy
oh so you are saying disable so i dont allow more then one event at a time? well there are many .blah so i need something more global. Also i prefer if i can do more then one at a time.
acidzombie24
just try the above code, if ".blah" are input elements it should work just fine, as many times as you want. Remember, you're re-enabling those elements in the complete callback.
jAndy
+1  A: 

I tried something similar to that...

here's the sample markup

<div id="links"><a href="#">link1</a><a href="#">link2</a></div>

then this is the jquery code

$('#links').click(function(e) {
        var link = $(e.target).closest('a');
        if ( link.length ) {
            setTimeout(function() {
                console.log(link.text());
            }, 2000);
            return false;
        }
    });;

I think you will still have the correct value in your "c" variable. In this example I still got two console logs "link1" and "link2" even after clicking both links at once before the 2 second timeout.

Hope this helps.

ricecake5
A: 

A simple test:

var i = 0;

var f = function() {
  var c = ++i;
  setTimeout(function() {
    alert(c);
  }, i*1000);
}

f();
f();
f();

// alerts 1, 2 and 3 after a little delay

shows your gut feeling is wrong.

Tgr
+1 who voted you down? and why?
acidzombie24
+3  A: 

The this keyword inside the onclick callback refers to the element the click was fired on.

This means that the variable c will always be the closest .comment element. Like if you click on 5 different .blah elements really fast, it will trigger 5 ajax calls, and all 5 success callbacks will have the proper scope copied in which it was defined.

So it is safe to do that, since the scope in where c is, is copied inside the success callback. Welcome to the power of JavaScript closures.

Luca Matteis