I have a slew of async
functions I'm using and I'm having a weird issue.
My code, working, looks like:
async mainAsyncFunc (metadata) {
let files = metadata.map(data => this.anotherAsyncFunc(data.url));
return Promise.all(files);
}
anotherAsyncFunc
function looks like:
async anotherAsyncFunc (url) {
return await axios({
url,
}).then(res => res.data)
.catch(err => {
throw err;
});
}
My issue comes when I try to append more data to what the first function (mainAsyncFunc
) returns. My thoughts are to do that in the map
, naturally, and when all is said and done, modified it looks like:
async mainAsyncFunc (metadata) {
files = metadata.map(data => {
return new Promise((resolve) => {
let file = this.anotherAsyncFunc(data.download_url);
let fileName = data.name;
resolve({
file,
fileName
});
});
});
return Promise.all(files);
}
If it's not clear, I'm getting the file itself like normal, and appending a fileName to it, then resolving that object back.
For some reason, this is returning a pending Promise, whereas I would expect it to wait for them to be fulfilled and then returned as a complete file and name in an object. Any help understanding what I'm doing wrong would be greatly appreciated.
I have a slew of async
functions I'm using and I'm having a weird issue.
My code, working, looks like:
async mainAsyncFunc (metadata) {
let files = metadata.map(data => this.anotherAsyncFunc(data.url));
return Promise.all(files);
}
anotherAsyncFunc
function looks like:
async anotherAsyncFunc (url) {
return await axios({
url,
}).then(res => res.data)
.catch(err => {
throw err;
});
}
My issue comes when I try to append more data to what the first function (mainAsyncFunc
) returns. My thoughts are to do that in the map
, naturally, and when all is said and done, modified it looks like:
async mainAsyncFunc (metadata) {
files = metadata.map(data => {
return new Promise((resolve) => {
let file = this.anotherAsyncFunc(data.download_url);
let fileName = data.name;
resolve({
file,
fileName
});
});
});
return Promise.all(files);
}
If it's not clear, I'm getting the file itself like normal, and appending a fileName to it, then resolving that object back.
For some reason, this is returning a pending Promise, whereas I would expect it to wait for them to be fulfilled and then returned as a complete file and name in an object. Any help understanding what I'm doing wrong would be greatly appreciated.
Share Improve this question edited Apr 3, 2017 at 21:30 Felix Kling 816k180 gold badges1.1k silver badges1.2k bronze badges asked Apr 3, 2017 at 20:51 ZachZach 5,07310 gold badges34 silver badges54 bronze badges 6 | Show 1 more comment2 Answers
Reset to default 13It looks like you've solved your issue, just as a bit of a pointer, you can further simplify your code as follows:
async anotherAsyncFunc (url) {
return (await axios({ url })).data;
}
async mainAsyncFunc (metadata) {
let files = metadata.map(async data => ({
file: await this.anotherAsyncFunc(data.download_url),
fileName: data.name
}));
return Promise.all(files);
}
Just solved the issue:
files = metadata.map(async (data) => {
let file = await this.anotherAsyncFunction(data.download_url);
let fileName = data.name;
return {
file,
fileName
};
});
I needed to wrap the anonymous function in async
so I could use await
inside of it. Hopefully this helps anyone else with a similar problem!
async
functions return promises. Nor can you turn a Promise-wrapped value into an ordinary value, you will always have toawait
or call.then
. Why did you expect to get an array? – Jared Smith Commented Apr 3, 2017 at 20:56Promise.all()
because I'm mapping over a dataset and returning the result of async function for each item. Thus creating an array. However, I just solved my own issue and am posting a solution now – Zach Commented Apr 3, 2017 at 20:58Promise.all
returns a Promise. Again, you cannot 'unwrap' a promise. You can only.then
it. – Jared Smith Commented Apr 3, 2017 at 20:58FileRetriever.mainAsyncFunc(metadata).then(contents => ...)
, and with my new working codecontents
is an array. – Zach Commented Apr 3, 2017 at 21:01await
is sugar over.then
. You cannot ever unwrap a promise. Its a logical impossibility in the general case, as there is no way to tell if a promise is resolved or not. – Jared Smith Commented Apr 3, 2017 at 21:06