Reputation: 1524
I'm trying to break down promises, as I want to eventually return the results of an SQL query within the myPromise
promise, so that I end of with a list of the results of a many SQL queries.
var myList = [];
for (let i = 1; i <= 20; i++) {
var myPromise = new Promise(function(resolve, reject) {
myList.push(myPromise);
resolve("ITEM " + i);
})
}
Promise.all(myList).then(function(values) {
console.log(values);
});
console.log("End");
Output:
[ undefined,
'ITEM 1',
'ITEM 2',
'ITEM 3',
'ITEM 4',
'ITEM 5',
'ITEM 6',
'ITEM 7',
'ITEM 8',
'ITEM 9',
'ITEM 10',
'ITEM 11',
'ITEM 12',
'ITEM 13',
'ITEM 14',
'ITEM 15',
'ITEM 16',
'ITEM 17',
'ITEM 18',
'ITEM 19' ]
How I understand how it works: My loop immediately appends a new promise to myList
, then when it's resolved the promise gets replaced with the string value from passed into resolve
.
It works well but I end up with 1 undefined value at the beginning. I have 20 items total which is expected, but one is undefined. Why is this?
Upvotes: 0
Views: 57
Reputation: 370729
The myPromise
you push to myList
is created after the Promise constructor runs. So, on the first iteration, myPromise
is undefined
(and on subsequent iterations, the last myPromise
is pushed to the array).
Construct the Promise, and then immediately push to the array in the same iteration instead:
var myList = [];
for (let i = 1; i <= 20; i++) {
var myPromise = new Promise(function(resolve, reject) {
resolve("ITEM " + i);
});
myList.push(myPromise);
}
Promise.all(myList).then(function(values) {
console.log(values);
});
console.log("End");
It might be clearer if you manually hoist the myPromise
(so that you see the code closer to how the interpreter runs it):
var myPromise;
var myList = [];
for (let i = 1; i <= 20; i++) {
myPromise = new Promise(function(resolve, reject) {
resolve("ITEM " + i);
});
myList.push(myPromise);
}
Promise.all(myList).then(function(values) {
console.log(values);
});
console.log("End");
Upvotes: 3
Reputation: 509
The first time, you are pushing myPromise
to myList
while it is still undefined.
You can fix this by avoiding the myPromise
variable altogether.
var myList = [];
for (let i = 1; i <= 20; i++) {
myList.push(new Promise(function(resolve, reject) {
resolve("ITEM " + i);
}))
}
or pushing to myList
afterwards.
for (let i = 1; i <= 20; i++) {
var myPromise = new Promise(function(resolve, reject) {
resolve("ITEM " + i);
})
myList.push(myPromise);
}
Upvotes: 3