Как эффективно агрегировать массив при вызове API обещаний? - PullRequest
3 голосов
/ 01 мая 2020

Я хочу выполнить серию функций 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;
    }
} 

1 Ответ

1 голос
/ 01 мая 2020

У вас есть три вещи:

  • Имя проверяемого свойства
  • Строка, которую вы передаете get
  • Результат свойство объекта (последнее кажется странным)

Вы можете определить массив объектов со значениями для них, например так:

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

тогда, если вы хотите сделать запрос параллельно с ними, вы можете использовать Promise.all, чтобы дождаться выполнения нескольких обещаний, затем набрать sh записи из полученного массива:

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 l oop вместо:

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;
    }
}
...