Reputation: 14098
This is basically my code, using q:
let d = Q.defer();
let result = {
name: 'peter'
};
d.resolve(result);
return d.promise;
However, I now need to perform a step based on a certain condition. This step is calling another object that also returns a promise. So I'm having nested promises, if that's the correct term.
Something like this:
let d = Q.defer();
let result = {
name: 'peter'
};
if (someParameter) {
otherService.getValue() // Let's say it returns 'mary'
.then((res) => {
result.name = res;
});
}
d.resolve(result);
return d.promise;
This doesn't work however (the name
property is still 'peter'). Probably due to the fact that my inner promise is resolved at a later moment?
I've also tried this, but it doesn't work if I call the otherService which returns a promise. It does work if I just set the value:
let d = Q.defer();
let result = {
name: 'peter'
};
d.resolve(result);
return d.promise
.then((data) => {
if (someParameter) {
// Works
data.name = 'john';
// Doesn't work
otherService.getValue()
.then((res) => {
data.name = res;
});
}
return data;
});
Here the name will be 'john', not 'mary'.
Clearly I'm misunderstanding promises, but I can't wrap my head around it.
Upvotes: 1
Views: 3310
Reputation: 664246
Using deferreds is deprecated. If at all, you should use the Q.Promise
constructor, but you don't even need that. Just use the Q
function to create a promise that is fulfilled with your value.
Now you can (and should) simplify your code to
let d = someParameter ? otherService.getValue() : Q('peter');
return d.then(res => ({
name: res
}));
Upvotes: 2
Reputation: 67296
Control flow with Promises is...fun?
Anyway, you are nearly there, you can embed a Promise
in a Promise
as well as chain them. However, if you are embedding them, you must return
the embedded Promise
chain:
let d = Q.defer();
let result = {
name: 'peter'
};
d.resolve(result);
return d.promise
.then((data) => {
if (someParameter) {
// Should work now that we return the Promise
return otherService.getValue()
.then((res) => {
data.name = res;
// And we have to return the data here as well
return data;
});
}
return data;
});
Promise
resolve
can take a value or another Promise
and it will handle the flow. So, when we return
inside a then
, the value we are returning can be another Promise
or just a value. The machinery will take care of unwrapping for us.
Upvotes: 1