【问题标题】:How to efficiently aggregate an array when calling promise APIs?调用 Promise API 时如何有效地聚合数组?
【发布时间】:2020-08-16 01:13:39
【问题描述】:

我想执行一系列 getData 函数,但前提是有数据要获取。然后我需要将所有结果编译成一个配对值数组来返回。

以下代码有效,但我需要对另外 7 批“if (card.x)...”执行类似操作 有什么更好的方法呢?

async function buildingCard(card) {
    let cardToCreate = []
    try {
        if (card.joke1) {
            // wixData.get returns a promise
            let joke = await wixData.get("jokes", card.joke1).then((results) => {
                cardToCreate.push({ "titleText1": results.title })
            })
        }
        if (card.quote1) {
            let quote = await wixData.get("quotes", card.quote1).then((results) => {
                cardToCreate.push({ "fancyText1": results.title })
            })
        }
        return cardToCreate

    } catch (error) {
        console.log("buildcard error: " + error);
        return error;
    }
} 

【问题讨论】:

  • 您想并行(全部相互重叠)还是串行(一个接一个)执行get 操作?
  • 另外,结果对象上的属性名称是否会这样变化?第一种情况是titleText1,第二种情况是fancyText1
  • 我已更改您的问题标题以准确反映问题。 “编译”一词在编程中具有特定含义,此处不适用。

标签: javascript arrays promise


【解决方案1】:

你有三个不同的地方:

  • 您正在检查的属性的名称
  • 你传递的字符串get
  • 对象的结果属性(最后一个看起来很奇怪)

您可以使用这些对象的值定义一个对象数组,如下所示:

let props = [
    {name: "joke1", key: "jokes", resultKey: "titleText1"},
    {name: "quote1", key: "quotes", resultKey: "fancyText1"},
    // ...
];

如果你想并行查询这些,你可以使用Promise.all 等待多个承诺解决,然后从结果数组中推送条目:

async function buildingCard(card) {
    // Define the stuff you'll do
    let props = [
        {name: "joke1", key: "jokes", resultKey: "titleText1"},
        {name: "quote1", key: "quotes", resultKey: "fancyText1"},
        // ...
    ];
    let cardToCreate = [];
    try {
        return Promise.all(props
            // Only the ones with values
            .filter(({name}) => card[name])
            // Map to the object to push
            .map(
                ({name, key, resultKey}) =>
                wixData.get(key).then(results => ({[resultKey]: results}))
            )
        );
    } catch (error) {
        console.log("buildcard error: " + error);
        return error;
    }
}

如果你想一次打一个电话,你可以改用for-of循环:

async function buildingCard(card) {
    // Define the stuff you'll do
    let props = [
        {name: "joke1", key: "jokes", resultKey: "titleText1"},
        {name: "quote1", key: "quotes", resultKey: "fancyText1"},
        // ...
    ];
    try {
        let cardToCreate = [];
        for (const {name, key, resultKey} of props) {
            if (card[name]) {
                const results = await wixData.get(key);
                cardToCreate.push({[resultKey]: results});
            }
        }
        return cardToCreate;
    } catch (error) {
        console.log("buildcard error: " + error);
        return error;
    }
}

【讨论】:

  • 在并行代码...await Promise.all(properties'我认为这应该是...await Promise.all(propsawait之前的...有什么作用?非常感谢
  • @mrpowergage - 是的,你是对的,这是一个编辑错误。在函数调用参数列表或数组文字中,... 就在数组 spreads out 之前,数组条目作为离散参数/条目。但是我在修复props/properties 的事情时意识到,没有理由创建一个空数组,然后将等待Promise.all 的结果推入其中;您可以直接从Promise.all 返回结果。我已经编辑过了。 :-)
  • 谢谢。我已经为我的情况做了几个星期,所以 wixData 收到了它所期望的 2 个属性。但是我收到了一个空的结果。任何想法/如何控制台日志/调试以查看发生了什么(我不确定我在箭头函数中的位置以放入日志)?
  • 调整:.map( // these changes made to props also ({key, collection, resultKey}) => wixData.get(collection, key).then(results => ({[resultKey]: results}))
猜你喜欢
  • 2021-06-17
  • 2017-07-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-09
相关资源
最近更新 更多