I'm trying to perform async function and then console log the results with the help of Promise . I'm afraid I haven't quite grasped the concept yet.
getlinks performs async action.
async function getLinks(param, data) {
return new Promise((resolve, reject) => {
let psub;
var name;
let g;
psub = checkForPsub(param);
var ultUrls = [];
_.each(data, o => {
title = sanitizeString(o.title);
if (psub == true) {
name = title + " u -- " + o.author;
} else {
name = title;
}
switch (o.domain) {
case "i.imgur.com":
{
// downloadImgur(o,name)
}
break;
case "imgur.com":
{
id = o.url.substring(o.url.lastIndexOf("/") + 1);
if (
o.url.includes("https://imgur.com/a/") ||
o.url.includes("https://imgur.com/gallery/") ||
o.url.includes("http://imgur.com/a/") ||
o.url.includes("http://imgur.com/gallery/")
) {
let urls = [];
let file_name;
axios
.get(
"https://api.imgur.com/3/album/" + id,
{ headers: { Authorization: "Client-ID 295ebd07bdc0ae8" } }
)
.then(res => {
let images = res.data.data.images;
_.each(images, function(v) {
var ext = v.link.split(".").pop();
if (ext == "gifv") {
ext = "mp4";
}
if (psub == true) {
file_name =
title + "--" + v.id + " " + "u--" + auth + "." + ext;
} else {
file_name = title + "--" + v.id + "." + ext;
}
let p = { url: v.link, file_name: file_name };
ultUrls.push(p);
});
})
.catch(err => {
console.log(err);
});
}
}
break;
case "i.redd.it":
{
}
break;
default:
console.log("other", o.domain);
}
}); //end each
return resolve(ultUrls);
});
}
I wanted to wait till getlinks finished performing tasks and then console log the result.
getLinks(sub,result).then(res => console.log({res}))
But the it logs the result as empty even before the getlink is finished.
This is how I would do it. Pushing the promises onto a promise array. THen calling Promise.resolve which will resolve all of them at the end.
async function getLinks(param, data) {
let psub;
var name;
let g;
let promises = [];
psub = checkForPsub(param);
var ultUrls = [];
_.each(data, o => {
title = sanitizeString(o.title);
if (psub == true) {
name = title + " u -- " + o.author;
} else {
name = title;
}
switch (o.domain) {
case "i.imgur.com":
{
// downloadImgur(o,name)
}
break;
case "imgur.com":
{
id = o.url.substring(o.url.lastIndexOf("/") + 1);
if (
o.url.includes("https://imgur.com/a/") ||
o.url.includes("https://imgur.com/gallery/") ||
o.url.includes("http://imgur.com/a/") ||
o.url.includes("http://imgur.com/gallery/")
) {
let urls = [];
let file_name;
// I would break this out into it's own function probabaly
promises.push(
axios
.get(
"https://api.imgur.com/3/album/" + id,
{ headers: { Authorization: "Client-ID 295ebd07bdc0ae8" } }
)
.then(res => {
let images = res.data.data.images;
_.each(images, function(v) {
var ext = v.link.split(".").pop();
if (ext == "gifv") {
ext = "mp4";
}
if (psub == true) {
file_name =
title + "--" + v.id + " " + "u--" + auth + "." + ext;
} else {
file_name = title + "--" + v.id + "." + ext;
}
let p = { url: v.link, file_name: file_name };
ultUrls.push(p);
});
})
.catch(err => {
console.log(err);
})
);
}
}
break;
case "i.redd.it":
{
}
break;
default:
console.log("other", o.domain);
}
}); //end each
return Promise.all(promises)
.then((yourData) => {
return yourData;
});
}
The simplest answer is you're promise is resolving ( return resolve(utlUrls)
) before your async code ( axios.get(...).then(...)
) completes.
This is a minimal example to reproduce your problem:
let timeout = ms => new Promise(resolve => setTimeout(() => resolve(ms), ms)); async function getLinks(urls) { return new Promise((resolve, reject) => { let ultUrls = []; urls.forEach(url => timeout(500).then(res => ultUrls.push(res))) return resolve(ultUrls); }); } getLinks([1, 2, 3]).then(a => console.log(a));
It doesn't work because we return ultUrls before we've filled it. We don't wait for the timeouts to complete.
To fix this, simply wait for the promises to complete using Promise.all
. Additionally removing some unnecessary wrapping of promises, we get:
let timeout = ms => new Promise(resolve => setTimeout(() => resolve(ms), ms)); function getLinks(urls) { let ultUrls = []; let promises = urls.map(url => timeout(500).then(res => ultUrls.push(res))) return Promise.all(promises).then(a => ultUrls); } getLinks([1, 2, 3]).then(a => console.log(a));
Furthermore, if you want to use the async/await
syntax, though it doesn't buy you much in this case where you have multiple requests in parallel, you could write it as:
let timeout = ms => new Promise(resolve => setTimeout(() => resolve(ms), ms)); async function getLinks(urls) { let ultUrls = []; let promises = urls.map(url => timeout(500).then(res => ultUrls.push(res))) await Promise.all(promises); return ultUrls; } getLinks([1, 2, 3]).then(a => console.log(a));
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.