我正在尝试执行异步功能,然后在 Promise 的帮助下控制台记录结果。恐怕我还没有完全掌握这个概念。
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);
});
}
我想等到getlinks完成执行任务,然后控制台记录结果。
getLinks(sub,result).then(res => console.log({res}))
但是即使在getlink完成之前,它也会将结果记录为空。
答案 0 :(得分:1)
这就是我要做的。将诺言推送到诺言数组。然后调用Promise.resolve,将最终解决所有问题。
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;
});
}
答案 1 :(得分:1)
最简单的答案是,您保证在完成异步代码(return resolve(utlUrls)
之前之前解决(axios.get(...).then(...)
)。
这是重现您的问题的最小示例:
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));
这是行不通的,因为在填充之前我们会返回ultUrl。我们不等待超时完成。
要解决此问题,只需等待使用Promise.all
完成的承诺即可。除了消除不必要的承诺包装外,我们得到:
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));
此外,如果您想使用async/await
语法,尽管在并行处理多个请求的情况下,它并不会给您带来很多好处,但是您可以将其编写为:
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));