Q: setTimeout firing immediately with jQuery? What I want to happen is when the ".slick-next" button is clicked, the browser waits 3 seconds, and then runs the loadPHP() function. Below is my code, which seems like it theoretically should work, but doesn't. What happens is that the setTimeout function runs once when the page loads, but after that clicking the next button doesn't do anything.
var timeout = null;

$(".slick-next").click(nextButton(timeout));

var nextButton = (function(timeout) {
    window.clearTimeout(timeout);
    timeout = setTimeout(function() {
        loadPHP();  
    }, 3000);
});

I tried wrapping the whole jQuery expression in a setTimeout, but that doesn't work either. What happens is that you can't click the button for 3 seconds, but then can click it endlessly.
setTimeout(function() {
    $(".slick-next").click(nextButton(timeout));
}, 3000));

Why is this behavior happening?

A: That's because you're already invoking the function while doing .click(nextButton(timeout)) and thus starting the timer.
Instead, pass a reference:


var timeout = null;
var clickCount = 0;

var loadPHP = function() {
  $('#output').text(clickCount + ': Loading from server ...');
};

var nextButton = function() {
  clickCount++;
  window.clearTimeout(timeout);
  timeout = setTimeout(loadPHP, 3000);
  $('#output').text('Timeout ' + timeout + ' set. Waiting 3s.');
};

$(".slick-next").click(nextButton);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="slick-next">Run</button>
<div id="output"></div>


... or use function.prototype.bind as suggested in one of the comments but it's not really required for what's desired here and it is a ECMA script 5.1 feature, thus not available in older JavaScript browser implementations.
Also of note: When assigning function expressions to variables, this must be done before the variable is used; otherwise one is passing an undefined value. To avoid this need, use declaration hoisting.

A: You want to attach nextButton as a click handler, not execute it immediately.
You could write :
$(".slick-next").click(nextButton);

except for the need to pass an argument. That's what .bind() is for :
$(".slick-next").click(nextButton.bind(null, timeout));

Also, the setTimeout expression will simplify :
timeout = setTimeout(loadPHP, 3000);


A: What I want to happen is when the ".slick-next" button is clicked, the browser waits 3 seconds and then runs the loadPHP() function
We could do this easily by setting a function as event handler bound to event click:
$(".slick-next").on("click",function(){
    setTimeout(function() {
        loadPHP();  
    }, 3000);
});

The problem with your code was that you were firing the click event by calling the click function $(".slick-next").click()

A: Drop the enclosing parens around the function because the expression on the right hand side is being evaluated for a value:
var nextButton = function(timeout) {
    window.clearTimeout(timeout);
    timeout = setTimeout(function() {
        loadPHP();  
    }, 3000);
};

