簡體   English   中英

Javascript:Promise實現中的錯誤

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM