[英]Javascript: Error in Promise implementation
我正在嘗試執行異步功能,然后在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完成之前,它也將結果記錄為空。
這就是我要做的。 將諾言推送到諾言數組。 然后調用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;
});
}
最簡單的答案是,您可以保證在異步代碼( axios.get(...).then(...)
)完成之前解析( return resolve(utlUrls)
)。
這是重現您的問題的最小示例:
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));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.