-1

Below jquery code segment works perfectly but an explicate $.Deferred() is created inside myFunction(). Is it possible to avoid this explicate $.Deferred() creation? Is it follow antipattern?

$(document).ready(function () {
     $.when(
         myFunction()
      )
     .then(function (result) {
             //Do rest of the work
      })
});    

function myFunction() {
     var deferred = $.Deferred();
     $.when(
            someOtherAction()
     )
     .then(function (result) {
            deferred.resolve(result)
     })

     return deferred.promise();
}

function someOtherAction()
{
     //Long running work...., returns either true or false after            
     //execution

     return true;
}
Sudipta Kumar Maiti
  • 1,669
  • 1
  • 12
  • 18

2 Answers2

2

Just a quick note... you don't need to use $.when when you only have one promise. You can just do:

myFunction().then(function(result){}
});

That being said, you need to create a $.Deferred object somewhere in order to return a promise. Some jQuery methods return you a promise already, like $.ajax (because they create a new $.Deferred internally).

Why not have someOtherAction() return a promise instead of a boolean? You can have it call deferred.resolve with the boolean (and/or any other variables you need). I don't think you really need myFunction().

gen_Eric
  • 223,194
  • 41
  • 299
  • 337
  • No, a function that can return synchronously should do so, and not create a promise for you. If you want to wrap a value in a promise (for whatever reason), just use `$.when` – Bergi Nov 02 '15 at 19:09
  • @Bergi: That's not quite how `$.when` works. `$.when` basically *combine* multiple promises into one. If the method is *synchronous*, then you don't need promises at all! – gen_Eric Nov 02 '15 at 19:50
  • @Bergi: If a single argument is passed to jQuery.when() and it is not a Deferred or a Promise, it will be treated as a resolved Deferred and any doneCallbacks attached will be executed immediately. http://api.jquery.com/jQuery.when/ – gen_Eric Nov 02 '15 at 19:51
  • Yes, if the method is synchronous, you don't need promises at all, so please don't suggest to return a promise instead of a boolean. But if you still want to do, you can just use `return $.when(true)` without needing to construct a deferred manually. – Bergi Nov 02 '15 at 20:52
0

you can return a Promise object from myFunction instead of a Deferred object and things will work as you expect:

$(document).ready(function() {
  $.when(myFunction())
    .done(function(result) {
      // ...
      console.log("all done");
    }).fail(function(err) {
      // ...
    });
});

function myFunction() {
  return ($.when(someOtherAction())
            .done(function(result) {
              return (result);
            }).fail(function(err) {
              // ...
            })
         );
}

function someOtherAction() {
  // ...
  for (var i = 0; i < 1000000; i++) { ; }
  return (true);
}

JSFiddle

Dan O
  • 6,022
  • 2
  • 32
  • 50