0

I am sending multiple requests to a API say "myapi/id". My ids could range from [0..10000]. Because sending all ids at once is very expensive, I would like to send in slice wait for it to be fetched and then send the next slice.

Here is the code I am using:

async function getSlice(data) {
    let promises = []
    data.map((key) => {
        promises.push(fetch("myapi/"+key)
        .then(res => res.json())
        .then((result) => console.log(result))) //I want to store the result in an array
    }
    await Promise.all(promises)
} 

function getAll(data) {
    for(let i=0; i<= data.length; i+=10) {
        getSlice(data.slice(i,i+10));
        //I want to wait for the previous slice to complete before requesting for the next slice
    }
}

getAll(ids)

However, the requests are being sent asynchronously/there is no waiting happening. I was wondering if there is an error in my code/ if there is any way to send multiple requests using a for loop and wait for them to complete before sending the next requests.

4
  • Is there any reason you would like to use Promise.all if you would like to call an API sequentially? (Other than saving data in an array) Commented Apr 28, 2020 at 23:39
  • So make another Promise.map? Instead of looping through data, map (a massaged version of ) data so that you can await Promise.all(...) that, too. Unless you need this to be synchronous (i.e. getSlice 0 needs to finish before getSlice 10 happens) in which case you may want to rethink why you're using async at all. Commented Apr 28, 2020 at 23:39
  • 1
    You want to chain promises synchronously. See this (the reduce trick) css-tricks.com/… Note: I would use forEach instead of map in your current setup Commented Apr 28, 2020 at 23:40
  • @JamesYoo I want to call it concurrently in a particular slice but call them sequentially from one slice to another. Commented Apr 28, 2020 at 23:50

2 Answers 2

1

You need to use await before async function if you want to wait for it for finish

async function getAll(data) {
    for(let i=0; i<= data.length; i+=10) {
        await getSlice(data.slice(i,i+10));
    }
}

getAll(ids).then(()=>console.log('all data processed')).catch(err=>/*handle 
error*/)

Ps. i think that you need to use Promise.allSettled method instead of Promise.all. If one of your request will return an error, you will get all chunk failed if you will use Promise.all. Promise.allSettled will wait for all results - positive or negative. Anothe old sollution is to use catch method for each request, like

 promises.push(fetch("myapi/"+key)
    .then(res => res.json())
    .then((result) => console.log(result))
    .catch((err)=>{/*handle error if needed*/; return null})

And after that you will have some nulls in array with results

Sign up to request clarification or add additional context in comments.

Comments

1

An efficient way of doing is always keep the requests being called (limiting the maximum number of parallel requests) instead of the way you are doing.

By using your way (easier) it will always wait for everything to return then checks if there is more data in the array and call the function again recursively or return everything if it is done. Hope it helps.

async function getSlice(data) {
    let promises = []
    data.map((key) => {
        promises.push(fetch("myapi/"+key)
        .then(res => res.json())
        .then((result) => console.log(result))) //I want to store the result in an array
    }
    await Promise.all(promises)
} 

function getAll(data, index=0, length=10) {
    const allResponse = [];  
    return getSlice(data.slice(index,q)).then(response => {
        allResponse.push(response);
        newLength = length + 11 > data.length ? data.length : length + 11;
        if (index + 10 > data.length) //it's over
         return allResponse;
        return getAll(data, index + 10, length +11);
})}

Promise.all(getAll(ids).then(arrayResponse=>console.log('dowhatever',arrayResponse))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.