Reputation: 495
I am new to Promises and I'm having a little trouble with the concept of waiting for a nested promise to finish all executions before resolving the original promise.
Original Code
function getSomething(text) {
return new Promise(function (resolve, reject) {
getElse(text).then(function (items) {
if (items.length !== 0) {
/* Stuff here */
getElseElse(box).then(function (moreItems) {
/* Stuff here */
return array;
}.then(function (array) {
var promise = new Promise(function (resolve, reject) {
/* anotherFunction() is asynchronous */
result = anotherFunction(array); <-- Spot 1
});
promise.then(function () { });
});
return resolve(result); <--- Spot 2
}
else {
return resolve(null);
}
});
});
};
Updated Code - better but still not fully working like I want.
function getSomething(text) {
return getElse(text).then(function (items) {
if (items.length !== 0) {
/* Stuff here */
return getElseElse(box).then(function (moreItems) {
/* Stuff here */
return array;
}).then(anotherFunction);
} else {
return null;
}
});
}
Then, inside of the individual View page, I have this:
getSomething(text).then(function (result) {
/* Do something here using result */
/* But result is undefined and I think still pending */
});
I have optimized the original function using Thomas's help but the original call inside the view still seems to be continuing before result
is formulated.
I want getSomething()
to full complete and return result
before I execute the code inside of the .then
that is inside the view. So far, that is not being accomplished.
I have found a couple posts that have pointed me in what I think is the correct direction of Promise.all
but I can't really seem to get anywhere with that information so I was hoping someone could help explain it for my specific situation.
The posts that have helped are:
The original issue was solved by Thomas in the marked answer. The final problem was solved inside of anotherFunction()
upon further inspection.
Originally:
function anotherFunction(array) {
return new Promise(function (resolve, reject) {
return anotherGet(parcels).then(function (list) {
/* Do stuff here without a return */
});
});
}
Fixed Version:
function anotherFunction(array) {
return anotherGet(parcels).then(function (list) {
/* Do stuff here */
return list;
});
}
Upvotes: 2
Views: 3754
Reputation: 12677
First, avoid the Promise/Deferred antipattern. Rarely you need to create your own promises, usually you have some function that returns a Promise; use that.
Second, for the outer Promise to wait for a nesed PRomise, you need to return that nested Promise to the outer Promise.
Returning a Promise inside of then()
will make the resulting Promise to resolve to the value of the Promise you retuned inside.
And last, something like .then(value => value)
or .then(value => Promise.resolve(someFunction(value)))
is pointless. Your wrapper around anotherFunction
basically just passed through the argument and returned the result.
So, your Pseudocode should look something like this:
function getSomething(text) {
return getElse(text).then(function (items) {
if (items.length !== 0) {
/* Stuff here */
return getElseElse(box).then(function (moreItems) {
/* Stuff here */
return array;
}).then(anotherFunction);
} else {
return null;
}
});
}
Upvotes: 6
Reputation: 26625
The basic trick is to make sure all of your resolve()
calls are inside of the nested promises' then()
methods.
Something along the lines of:
function getSomething(text) {
return new Promise(function (resolve, reject) {
getElse(text).then(function (items) {
if (items.length !== 0) {
/* Stuff here */
getElseElse(box).then(function (moreItems) {
/* Stuff here */
return array;
}.then(function (array) {
var promise = new Promise(function (resolve, reject) {
result = anotherFunction(array); <-- Spot 1
});
promise.then(function () { });
resolve(result); <--- Spot 2
});
}
else {
resolve(null);
}
});
});
};
If it needs to be nested in the promise.then()
above, just stick it in there instead.
Also note that you don't need to return your resolves. Just call them.
Upvotes: 1