【问题标题】:Why is this async function failing to return any data?为什么这个异步函数没有返回任何数据?
【发布时间】:2018-12-28 05:49:21
【问题描述】:

所以,快速概述一下,这个函数是一个更大的应用程序的一部分,它接收 JSON 数据并准备好由 Handlebars 呈现,然后用于生成 PDF。这个特殊的函数一直让我很伤心,根据我对 async/await 工作原理的理解,数据应该由函数底部的return returnArray 返回。然而,这不会发生,而是返回空数组。任何人都可以提供有关为什么会这样的见解吗? (注意,当数据被推送时,我已经检查过 iarr 中是否存在数据,就好像在 for 循环开始之前触发了 return 语句。)

async function getPackageItem(item) {
  try {
    let returnArray = []
    if (fs.existsSync(__dirname + "/../json/" + item.sku + ".json")) {
      var file = fs.readFileSync(__dirname + "/../json/" + item.sku + ".json")
    } else {
      var file = fs.readFileSync(__dirname + "/../json/box.json")
    }
    const tb = JSON.parse(file);
    for (var a = 0; a < item.quantity; a++) {
      let iarr = [];
      if (tb) {
        tb.forEach(function(entry) {
          ShopifyAuth.get('/admin/products/' + entry.product_id + '.json', (err, productData) => {
            if (!err) {
              ShopifyAuth.get('/admin/products/' + entry.product_id + '/metafields.json', (err, metafieldData) => {
                if (!err) {
                  var itemObject = {};
                  var metaCounter = 0;
                  metafieldData.metafields.forEach(function(metadata) {
                    switch(metadata.key) {
                      case "notes": {
                        itemObject.wm_notes = metadata.value;
                        metaCounter++
                        break;
                      }
                      case "title": {
                        itemObject.title = metadata.value;
                        metaCounter++
                        break;
                      }
                      case "vintage": {
                        itemObject.year = metadata.value;
                        metaCounter++;
                        break;
                      }
                      case "shelfid": {
                        itemObject.shelf_id = metadata.value;
                        metaCounter++;
                        break;
                      }
                      case "bottleprice": {
                        itemObject.bottle_price = metadata.value;
                        metaCounter++;
                        break;
                      }
                      default: {
                        metaCounter++;
                        break;
                      }
                    }
                    if(metaCounter === metafieldData.metafields.length) {
                      itemObject.vendor = productData.product.vendor;
                      if (itemObject.title == undefined) {
                        itemObject.title = productData.product.title
                      }
                      if (itemObject.wm_notes == undefined) {
                        itemObject.wm_notes = " "
                      }
                      if (itemObject.year == undefined) {
                        itemObject.year = "Unspecified"
                      }
                      if (itemObject.shelf_id == undefined) {
                        itemObject.shelf_id = "N/A"
                      }
                      if (productData.product.images[1] == undefined) {
                        if (productData.product.images[0]) {
                          itemObject.logo = productData.product.images[0].src;
                        } else {
                          itemObject.logo = '';
                        };
                      } else {
                        itemObject.logo = productData.product.images[1].src;
                      }
                      itemObject.quantity = item.quantity;
                      iarr.push(itemObject)
                      if(iarr.length == tb.length) {
                        returnArray.push(iarr);
                      }
                    }
                  });
                } else {
                  throw Error('Error retrieving product metadata');
                }
              })
            } else {
              throw Error('Error retrieving product data');
            }
          })
        })
      } else {
        throw Error('Error loading JSON for specified box');
      }
    }
    return returnArray;
  } catch (e) {
    console.log(e)
  }
}

编辑:这就是我在凌晨 3 点编写代码所得到的,不知道我是怎么错过的。感谢您的反馈。

【问题讨论】:

  • 为了让它按照你想要的方式工作,你必须 await 函数中的异步调用。这些也需要先得到承诺。
  • 除了awaiting 结果之外,如果您使用的库不支持Promises,我强烈建议使用 Promisify。
  • @jhpratt 出于某种原因,我完全忽略了其中有一个回调的事实:/ 一直在使用promisify,它是一个非常棒的包装器。

标签: javascript node.js loops asynchronous async-await


【解决方案1】:

您标记了您的函数async,但您没有在其中的任何地方使用await,因此您没有获得使用async 的任何好处。它不会让你的函数神奇地同步,你仍然需要小心管理异步性。

如果ShopifyAuth.get 支持返回一个promise,那么await 在结果上而不是传递回调并且您的代码将起作用,否则构造一个Promise,在promise 中执行异步操作,并从函数返回promise。

async function getPackageItem(item) {
  let result = new Promise((resolve, reject) => {
    // all your ShopifyAuth stuff here
    if (err) {
      reject(err);
    }
    resolve(returnArray);
  });
  return result;
}

【讨论】:

    猜你喜欢
    • 2021-01-15
    • 1970-01-01
    • 2021-10-31
    • 2013-03-25
    • 1970-01-01
    • 2020-12-25
    • 2020-09-28
    • 2019-03-10
    相关资源
    最近更新 更多