Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery.Deferred().then, how to resolve with multiple parameters

So my API expects that when a particular deferred is resolved it gets 2 params.

fn().done(function(arg1, arg2) {
  console.log(arg1, arg2);
}).fail(function(err) {
  console.error(err);
});

Now relating to the fn function above, it needs to first wait for some other deferred to return before resolve.

function other() {
  // stubbed out to always resolve
  return $.Deferred().resolve().promise();
}

function fn() {
  return other().then(function() {
    return [1, 2];
  });
}

But this is not working, because arg1 will come as [1, 2] and arg2 will be undefined. I cannot figure out how to return something from Deferred.then() first success filter function argument so that the resulting piped deferred resolves with multiple arguments.

Of course I can do this:

function fn() {
  var done = $.Deferred();
  other().done(function(){
    done.resolve(1, 2);
  }).fail(function(){
    done.reject.apply(done, arguments);
  });
  return done.promise();
}

But that is not nearly as elegant as using .then() and I now need to worry about the negative failure case API each time even though I know that I'm merely piping the rejected state through.

And yes, I could also change fn() api to resolve with an array, but I am really hoping there is an elegant solution to this.

like image 287
codefactor Avatar asked Jul 11 '14 18:07

codefactor


People also ask

What is deferred resolve in JQuery?

resolve() method in JQuery is used to resolve a Deferred object and call any doneCallbacks with the given arguments. Syntax: deferred.resolve([args]) Parameters: args: This is optional parameters and is arguments which are passed to the doneCallbacks.

What is deferred () used for?

Deferred() method. It can register multiple callbacks into callback queues, invoke callback queues, and relay the success or failure state of any synchronous or asynchronous function. The Deferred object is chainable, similar to the way a jQuery object is chainable, but it has its own methods.

What is JQuery deferred and promise object?

A deferred object is an object that can create a promise and change its state to resolved or rejected . Deferreds are typically used if you write your own function and want to provide a promise to the calling code. You are the producer of the value. A promise is, as the name says, a promise about future value.

What is defer in promise?

The deferred. promise() method allows an asynchronous function to prevent other code from interfering with the progress or status of its internal request.


1 Answers

You will have to invoke resolve() or reject() in order to pass multiple arguments.

.then() doesn't include any mechanisms for "spreading" a returned collection. It'll just keep the collection intact as the 1st argument.

But, it will interact with a Deferred or promise that's returned. From the paragraph starting with "As of jQuery 1.8":

These filter functions can return a new value to be passed along to the promise's .done() or .fail() callbacks, or they can return another observable object (Deferred, Promise, etc) which will pass its resolved / rejected status and values to the promise's callbacks.

So, you could use your example of other() as the basis for fn() to keep it fairly succinct with another Deferred():

function fn() {
    return other().then(function () {
        return $.Deferred().resolve(1, 2).promise();
    });
}

fn().then(function (a, b) {
    console.log(arguments.length, a, b); // 2 1 2
});

http://jsfiddle.net/cqac2/

like image 84
Jonathan Lonowski Avatar answered Oct 21 '22 11:10

Jonathan Lonowski