Reputation: 40436
I have some functions that return jQuery Deferred objects and I'm having trouble getting my head around chaining them and processing the results.
Consider the following example:
const start = Date.now();
// Print a message with a timestamp.
function log (v) {
console.log(`${Date.now() - start} ${v}`);
}
// Return a deferred function that resolves 1 second later with 'value'.
function test (value) {
log(`test(${value})`);
return $.Deferred(function (def) {
window.setTimeout(function () {
log(`resolve(${value})`);
def.resolve(value);
}, 1000);
});
}
// Example:
test(42)
.then(function (v) { log(v); })
.then(test(99))
.then(function (v) { log(v); })
.then(function () { log('done'); });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
This is supposed to run test(42)
, then do something with its results, then run test(99)
then do something with those results, all in order. However, it actually outputs (first number is ms since program started):
0 test(42)
0 test(99)
1003 resolve(42)
1003 42
1003 undefined <-- supposed to be 99
1005 done
1005 resolve(99)
So both of the test
s get called at the same time right at the start, and everything else is off. What I want it to output is something like:
0 test(42)
1000 resolve(42)
1000 42
1000 test(99)
2000 resolve(99)
2000 99
2000 done
How can I make this work? I tried returning $.Deferred(...).promise()
, with no change in behavior, and I also tried using done
instead of then
but the only change was it printed 42
a second time instead of undefined
.
Upvotes: 2
Views: 43
Reputation: 24965
Each deferred only resolves once. For each deferred chain, you have to attach them correctly. Also the second call to test needs to be in a function so that it does not execute immediately.
const start = Date.now();
// Print a message with a timestamp.
function log (v) {
console.log(`${Date.now() - start} ${v}`);
}
// Return a deferred function that resolves 1 second later with 'value'.
function test (value) {
log(`test(${value})`);
return $.Deferred(function (def) {
window.setTimeout(function () {
log(`resolve(${value})`);
def.resolve(value);
}, 1000);
});
}
// Example:
test(42)
.then(function (v) { log(v); })
.then(function () {
test(99)
.then(function (v) { log(v); })
.then(function () { log('done'); });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Upvotes: 1