I have the following code:
someService.fnReturnsPromise()
.then(function () {
return someService.fnReturnsAnotherPromise(someArg);
})
.then(function (resultsOfSecondFn) {
// do stuff with results
});
I feel as if this should work; however, resultsOfSecondFn
isn't actually the results, it's the promise itself that I returned. To make it work the way I want, I have to do this:
someService.fnReturnsPromise()
.then(function () {
return someService.fnReturnsAnotherPromise(someArg);
})
.then(function (promiseReturn) {
promiseReturn.then(function (results) {
// do stuff with results
});
});
This is the pseudo-code for fnReturnsAnotherPromise
:
someService.fnReturnsAnotherPromise = function (arg1) {
return anotherService.anotherFnThatReturnsPromise(arg1);
};
So really, it's just one extra layer, but a promise is getting returned either way. The code for anotherFnThatReturnsPromise
is the simple paradigm of $q.defer()
, return dfd.promise
with some resolve()
s.
Promises like Angular's are Promises/A+ compliant and are guaranteed to recursively assimilate promises. This is exactly to avoid nesting and simplify things like your case and is the point of promises.
So even if you have a promise that returns and a promise that returns a promise you can unwrap it in a single .then
call. For example:
var p = $q.when(1); // Promise<Int>
var p2 = $q.when().then(function(){ return p; }); // Promise<Promise<Int>>
var p3 = $q.when().then(function(){ return p2; }); // Promise<Promise<Promise<Int>>>>
p3.then(function(result) {
console.log(result); // Logs 1, and Int and not p2's type
});
Or in your example:
someService.fnReturnsPromise()
.then(function() {
return someService.fnReturnsAnotherPromise(someArg);
})
.then(function(resultsOfSecondFn) {
// do work with results, it is already unwrapped
});
See this comparison with another language for perspective on promises not unwrapping.