This is my first time using promises so i'm sure there are pretty dumb mistakes here. What im trying to do, is send a http request thats in a for loop.
When doing this without the promise, i can run this loop fine and everything works properly. however, when I do this with the promise, it only returns one object (should be multiple, as its sending multiple requests)
This is my code
function run(o,initialvalue){
const test = new Promise( (resolve,reject) => {
const collectionCountUrl = 'https://x.io/rpc/Query?q=%7B%22%24match%22%3A%7B%22collectionSymbol%22%3A%22'+o.name+'%22%7D%2C%22%24sort%22%3A%7B%22takerAmount%22%3A1%2C%22createdAt%22%3A-1%7D%2C%22%24skip%22%3A'+initialvalue+'%2C%22%24limit%22%3A500%7D'
promises = []
for(i=0; i < o.count(/*in this case 60, so 3 requests*/); i+= 20){
$.get(collectionCountUrl).success(resolve).fail(reject) // This should be sending multiple of the requests above, correct? ^
}
})
test.then(function(data){
console.log(data) // this should return the data from each request? im not sure
})
}
I've tried to check out this post to see if I was setting up the for loop wrong but I dont think I am. Promise for-loop with Ajax requests
One promise is for a single result. You have to wrap a each request in a seperate promise (move the constructor call into the loop), and store the promises in an array.
Then, you can use aggregator methods like Promise.all (others being Promise.allSettled, Promise.race and Promise.any) to get a single promise of an array of results, that you can wait for.
Like this:
function run(o,initialvalue){
const collectionCountUrl = 'https://x.io/rpc/Query?q=%7B%22%24match%22%3A%7B%22collectionSymbol%22%3A%22'+o.name+'%22%7D%2C%22%24sort%22%3A%7B%22takerAmount%22%3A1%2C%22createdAt%22%3A-1%7D%2C%22%24skip%22%3A'+initialvalue+'%2C%22%24limit%22%3A500%7D'
const promises = []
// ^^^^^----+--- don't forget to declare all your variables
// vvv--+
for(let i=0; i < o.count(/*in this case 60, so 3 requests*/); i+= 20){
promises.push(new Promise( (resolve,reject) => {
$.get(collectionCountUrl).success(resolve).fail(reject)
}))
}
//You've got an array of promises, let's convert it to a single one that resolves when everything's done:
const test = Promise.all(promises)
test.then(function(data){
//This will run when all the requests have succeeded
//`data` is an array of results
console.log(data)
})
}
This will work, but there's an even better way!
jQuery's $.Deferred objects (like the one you're getting from $.get) also have a .then() method like promises do, and while it's not a real promise, you can use it like if it was. Such objects are called thenables.
So, instead of this thing...
promises.push(new Promise( (resolve,reject) => {
$.get(collectionCountUrl).success(resolve).fail(reject)
}))
...you can just do this:
promises.push( $.get(collectionCountUrl) )
So, here's the final code:
function run(o,initialvalue){
const collectionCountUrl = 'https://x.io/rpc/Query?q=%7B%22%24match%22%3A%7B%22collectionSymbol%22%3A%22'+o.name+'%22%7D%2C%22%24sort%22%3A%7B%22takerAmount%22%3A1%2C%22createdAt%22%3A-1%7D%2C%22%24skip%22%3A'+initialvalue+'%2C%22%24limit%22%3A500%7D'
const promises = []
for(let i=0; i < o.count(/*in this case 60, so 3 requests*/); i+= 20){
promises.push( $.get(collectionCountUrl) )
}
//You've got an array of promises, let's convert it to a single one that resolves when everything's done:
const test = Promise.all(promises)
test.then(function(data){
//This will run when all the requests have succeeded
//`data` is an array of results
console.log(data)
})
}