RobertAKARobin
RobertAKARobin

Reputation: 4260

jQuery chained events aren't firing

When I run this in Chrome, "A" and "B" are logged successfully, but the program never reaches "C". Why is that?

function doSomething(){
    var chain   = $.Deferred();

    console.log("B");

    chain.then(function(){
        console.log("C");
    }).then(function(){
        console.log("D");
    });
}

$(document).ready(function(){

    $("body").click(function(){
        console.log("A")
        doSomething();
    });

});

I've spent the past 30 minutes trying to find an answer, but everything seems to beyond what I'm trying to accomplish.

Upvotes: 0

Views: 53

Answers (2)

ssube
ssube

Reputation: 48327

The $(document).ready event is fired when the document loads, handled by jQuery, so that one is called pretty early on. It then binds a click handler to body, which is fired when a click event is detected. That logs "start" and immediately calls doSomething, which creates a Deferred and logs "middle".

You never actually do anything with that Deferred, however. You bind a callback when it is resolved, but never resolve it. Thus, the callback is never fired.

Returning the Deferred and calling its resolve method (with or without args) should fix this. You may want to call it later, from a timeout, or immediately with args from the event. Either way, you need to resolve (or reject) the promise at some point.

function doSomething(){
  var chain = $.Deferred();

  console.log("middle");

  chain.then(function(){
    console.log("end");
  });

  return chain;
}

$(document).ready(function(){
  $("body").click(function(){
    console.log("start")
    var dfd = doSomething();
    dfd.resolve();
  });
});

Upvotes: 3

Oleksandr T.
Oleksandr T.

Reputation: 77502

You should call .resolve, like this

function doSomething(){
    var chain   = $.Deferred();

    console.log("middle");

    chain.then(function(){
        console.log("end");
    });

    chain.resolve();
}

Upvotes: 3

Related Questions