Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I dynamically add a deferred to the promise from this jsFiddle?

Regarding this jsFiddle, I am trying to dynamically add a "deferred" which is created when an event triggers, so the done callback is only called when all deferred are resolved, including those added later:

Relevant code:

var promises = [ deferred1, ... ];
var p = when.all(promises).then(function() {
  console.log('All done!!');
  //! trigger
});

promises.push( deferredFromEvent ); // << ignored

update: suggestions using Q or jQuery are welcome, I am looking for one that works

like image 740
Hontoni Avatar asked Feb 19 '13 16:02

Hontoni


Video Answer


1 Answers

Treat your fixed promises as a separate bundle than the dynamic one(s).

Wait on the bundled promises and then pipe their combined outcome through a $.when() on an initially empty array. You can dynamically push new promises into this array any time.

http://jsfiddle.net/atesgoral/YVkVa/1/

HTML:

<p>You have 5 seconds to inject!</p>
<button id="inject">Inject Deferred 3</button>
<button id="resolve">Resolve Deferred 3</button>
<p>Deferred 1: <span id="dfd1">pending<span></p>
<p>Deferred 2: <span id="dfd2">pending<span></p>
<p>Deferred 3: <span id="dfd3">pending<span></p>
<h1 id="result"></h1>

JavaScript:

var dfd1 = $.Deferred(),
    dfd2 = $.Deferred(),
    fixed = [ dfd1.promise(), dfd2.promise() ],
    multiplexed = $.when.apply($, fixed), // Bundle the fixed ones
    reservoir = []; // Reservoir for dynamic promises

// The solution to your problem lies here. The rest is scaffolding.
var ultimate = multiplexed.pipe(function () {
    return $.when.apply($, reservoir);
});

ultimate.done(function() {
    $("#result").text("Done!");
});

window.setTimeout(function () {
    dfd1.resolve();
    $("#dfd1").text("resolved");
}, 2500);

window.setTimeout(function () {
    dfd2.resolve();
    $("#dfd2").text("resolved");
}, 5000);

var dfd3 = $.Deferred();

$("#inject").click(function () {
    reservoir.push(dfd3.promise());
});

$("#resolve").click(function () {
    dfd3.resolve();
    $("#dfd3").text("resolved");
});
like image 75
Ates Goral Avatar answered Oct 17 '22 09:10

Ates Goral