Nov 11, 2022 03:25 PM
I am trying to use Promise.all to asynchronously get data from an array of urls. I’m fairly new to promises but as far as I understand the below code should work? The code executes but no response is logged from the promise.all
Promise.all(urls.map(u=>fetch(u,options))).then(response=>{
console.log(response[0])
}
Solved! Go to Solution.
Nov 11, 2022 05:03 PM
Welcome to Airtable community!
What you are missing is that the top level Promise needs to be resolved before the script ends:
const masterPromiseResolved = await Promise.all(
urls.map(u=>fetch(u))).then(
responses=>{ responses.map(response=>console.log(response.status))}
)
Note also that resolved Promise.all will return array of results, in this case “fetch responses”. Logging
a single fetch response (response[0]
) doesn’t show anything interesting, so I changed it to response.status
for each returned response.
I am guessing that likely you would like to log the actual data? That means even longer chain…
const masterPromiseResolved = await Promise.all(
urls.map(u=>fetch(u).then(response => response.json()))).then(
responseArrayWithData=> responseArrayWithData.map( data=> console.log(data)))
or you can log it as a single object after resolving the Promise:
const masterPromiseResolved = await Promise.all(
urls.map(u=>fetch(u).then(response => response.json())))
console.log(masterPromiseResolved)
Putting all those requests into a single Promise, does work much faster vs asynchronous requests. I tested with 5 requests. BTW, I wonder if there would be an upper limit of number of requests that Airtable script can generate :thinking: .
If the chain above gets too messy , there are not too many URLs (which respond before script timeout) and you want to reduce brain overhead → you always try a simpler slower async/await method, which is:
for (let url of urls) {
const response = await fetch(url)
console.log(await response.json())
}
I hope that helps!
Nov 11, 2022 05:03 PM
Welcome to Airtable community!
What you are missing is that the top level Promise needs to be resolved before the script ends:
const masterPromiseResolved = await Promise.all(
urls.map(u=>fetch(u))).then(
responses=>{ responses.map(response=>console.log(response.status))}
)
Note also that resolved Promise.all will return array of results, in this case “fetch responses”. Logging
a single fetch response (response[0]
) doesn’t show anything interesting, so I changed it to response.status
for each returned response.
I am guessing that likely you would like to log the actual data? That means even longer chain…
const masterPromiseResolved = await Promise.all(
urls.map(u=>fetch(u).then(response => response.json()))).then(
responseArrayWithData=> responseArrayWithData.map( data=> console.log(data)))
or you can log it as a single object after resolving the Promise:
const masterPromiseResolved = await Promise.all(
urls.map(u=>fetch(u).then(response => response.json())))
console.log(masterPromiseResolved)
Putting all those requests into a single Promise, does work much faster vs asynchronous requests. I tested with 5 requests. BTW, I wonder if there would be an upper limit of number of requests that Airtable script can generate :thinking: .
If the chain above gets too messy , there are not too many URLs (which respond before script timeout) and you want to reduce brain overhead → you always try a simpler slower async/await method, which is:
for (let url of urls) {
const response = await fetch(url)
console.log(await response.json())
}
I hope that helps!
Nov 12, 2022 07:45 AM
Thanks so much Greg, this is exactly what I needed!
This is the final code I ended up using and then I iterate through the master promise. I was using fetch in a loop prior to this but was hitting the execution limit too frequently.
const masterPromise = await Promise.all(urls.map(u=>fetch(u,options).then(resp=>resp.json())))