【问题标题】:Promise returns undefined - loop inside PromisePromise 返回 undefined - 在 Promise 中循环
【发布时间】:2020-11-28 11:47:59
【问题描述】:

在我的应用程序中,我有一个返回承诺的函数。我在该函数中所做的是,等待 DOM 中的图像可用并提取该元素以生成它的 base64 数据。

getCodesOfOneMerchant(merchantDataEntry: MerchantData) {

    var codesOfMerchant = [];

    return new Promise(async (resolve, reject) => {

      for (let index = 0; index < merchantDataEntry.qrPayloadList.length; index++) {

        const value = merchantDataEntry.qrPayloadList[index];
        const payLoad = value.qrPayload
        this.qrvalue = payLoad;

        while (!document.querySelector(".qrcode img")) {
          await new Promise(r => setTimeout(r, 500));
          console.log("waiting for qr");
        }
        console.log("QR element is available");
        const qrEle = document.getElementById('qrcode');
        let imgBase64Data = this.getBase64Image(qrEle.firstChild.firstChild);

        console.log('Base64 = ' + imgBase64Data);

        var qrName = merchantDataEntry.serviceName + "-" + value.branch + "-" + value.mobile;

        let userQr: UserQr = new UserQr();
        userQr.name = qrName;
        userQr.qr = imgBase64Data;

        codesOfMerchant.push(userQr);
        console.log('1')
        
        if (index == merchantDataEntry.qrPayloadList.length - 1) {
          resolve();
        }
      }
      console.log('2')
      console.log('Returning data = ' + JSON.stringify(codesOfMerchant));
      return codesOfMerchant;

    });
}

下面是调用上面一个的函数。

async downloadQrCodesOfAllSelectedMerchants() {

    var qrCodesForAllMerchants = [];

    const filteredData = this.merchantDataList.filter(entry => entry.qrSelected);

    const promises = filteredData.map(async (value) => {
      const qrCodesOfMerchant = await this.getCodesOfOneMerchant(value);
      return qrCodesOfMerchant;
    });

    const qrCodesOfAll = await Promise.all(promises);

    console.log('HELLO');

    console.log(qrCodesOfAll); // this prints undefined

 
    console.log('DONE')
}

即使我在第一个方法中返回了 Promise,调用函数仍然收到 undefined。我不明白那里出了什么问题。

如您所见,我只是在返回之前记录数据以返回到第二个函数内的控制台。数据就在那里。

有人可以在这里帮助我吗?谢谢你..!

【问题讨论】:

标签: javascript angular typescript promise async-await


【解决方案1】:

在下面代码的被调用函数中

const promises = filteredData.map(async (value) => {
  const qrCodesOfMerchant = await this.getCodesOfOneMerchant(value);
  return qrCodesOfMerchant;
});

您已经在等待 getCodesOfOneMerchant 方法的响应,该方法将自行解决该承诺。

相反,您只需使用 Promise.all(promises) 转储 promises 数组中的所有 promise 并等待它们一次

const promises = filteredData.map(value => this.getCodesOfOneMerchant(value))
const qrCodesOfAll = await Promise.all(promises);

这会将 qrCodesOfAll 作为已解决的承诺数组提供

此外,执行器函数正在返回一个承诺,但承诺永远不会被解决。被调用者永远不会收到来自 promise 的返回值,即 codesOfMerchant。您将需要使用

来解决该承诺
resolve(codesOfMerchant)

现在将codeOfMerchant的值返回给被调用者

【讨论】:

  • 请检查更新的答案,您没有解决执行器功能中的承诺。需要解析一个 promise 才能返回数据。
  • 在 resolve 中添加 codesOfMerchant 就可以了。但是,在解决问题之前,我没有做出您建议的更改。
【解决方案2】:

您需要删除 return new Promise(async (resolve, reject) =&gt; { 行,然后将 getCodesOfOneMerchant 本身设为 async

async getCodesOfOneMerchant(merchantDataEntry: MerchantData) { /*
^^^^^ */
  const codesOfMerchant = [];
  for (const value of merchantDataEntry.qrPayloadList) {
    this.qrvalue = value.qrPayload;

    while (!document.querySelector(".qrcode img")) {
      await new Promise(r => setTimeout(r, 500));
      console.log("waiting for qr");
    }
    console.log("QR element is available");
    const qrEle = document.getElementById('qrcode');
    let imgBase64Data = this.getBase64Image(qrEle.firstChild.firstChild);
    console.log('Base64 = ' + imgBase64Data);

    const userQr: UserQr = new UserQr();
    userQr.name = merchantDataEntry.serviceName + "-" + value.branch + "-" + value.mobile;
    userQr.qr = imgBase64Data;

    codesOfMerchant.push(userQr);
  }
  return codesOfMerchant;
}

【讨论】:

  • 让我看看。但是,在解析构造函数中添加了我需要解析的内容后,我当前的实现开始工作。顺便说一句,我认为这个解决方案不会将异步函数作为执行者传递给你在评论中提到的作为反模式的承诺:) 不是吗?
  • @vigamage 是的,删除该行可以解决问题
猜你喜欢
  • 1970-01-01
  • 2014-05-12
  • 1970-01-01
  • 2023-04-01
  • 1970-01-01
  • 2022-12-07
  • 2019-03-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多