Как использовать обещания, чтобы l oop не зависало - PullRequest
0 голосов
/ 01 мая 2020

Я пытаюсь выполнить l oop через записи в базе данных, чтобы скомпилировать массив (cardsToInsert), который я запишу в другую базу данных.

Я застрял, потому что массив записывал в базы данных до того, как l oop закончится, я знаю, что мне нужно использовать функции promises / asyn c для достижения того, чего я хочу, но я почти уверен, что что-то не так с моими обещаниями.

Код работает для нескольких циклов (примерно 6-10 циклов, он должен l oop 16 раз), но затем зависает при попытке во время wixData.get (или зависает на другом обещании, которое является частью buildCard).

// wixData.get is a function that returns a promise

async function loopCards(cardsToGet) {
    let writeCard
    let buildCard
    for (let index = 0; index < cardsToGet.length; index++) {

        const cardToGet = cardsToGet[index].card
        buildCard = await wixData.get("Card", cardToGet)
            .then((card) => {
                return card
            })
            .catch((err) => {
                let errorMsg = err;
                return errorMsg
            });
        writeCard = await buildingCard(buildCard)
        cardsToInsert.push(writeCard)
    }
    return cardsToInsert
}

Что я делаю не так? (или что является ключевым, что я делаю неправильно, что останавливает эту работу, я уверен, что здесь есть что улучшить!)

ОБНОВЛЕНИЕ

Теперь я обновил код, и он прекрасно просматривается.

async function loopCards(cardsToGet) {
console.log('Start')
let writeCard
let buildCard

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

    const cardToGet = cardsToGet[index].card
    buildCard = wixData.get("Card", cardToGet)
        .then(async (card) => {
            writeCard = await buildingCard(card)
            cardsToInsert.push(writeCard)
        })
        .catch((err) => {
            let errorMsg = err;
            return errorMsg
        });

}
return cardsToInsert
}

Как заставить его ждать, пока l oop не завершится sh, прежде чем, наконец, вернуть cardsToInsert?

1 Ответ

0 голосов
/ 01 мая 2020

Ваше сочетание async/await и .then на самом деле не наилучшая практика

Это должно сработать и вернется после заполнения cardsToInsert

async function loopCards(cardsToGet) {
    const cardsToInsert = [];
    for (let cardToGet of cardsToGet) {
        try {
            const card = await wixData.get("Card", cardToGet);
            const writeCard = await buildingCard(card);
            cardsToInsert.push(writeCard);
        }
        catch(err) {
            let errorMsg = err;
            return errorMsg;
        }
    }
    return cardsToInsert;
}

Более того, вам действительно не нужно обрабатывать какие-либо ошибки здесь, так как вызывающая функция может сделать это

Так что это становится еще проще

async function loopCards(cardsToGet) {
    const cardsToInsert = [];
    for (let cardToGet of cardsToGet) {
        const card = await wixData.get("Card", cardToGet);
        const writeCard = await buildingCard(card);
        cardsToInsert.push(writeCard);
    }
    return cardsToInsert;
}

, тогда его использование может быть похоже на

loopCards(cards)
.then(result => doSomethingWihtResult)
.catch(error => handleError);

или при вызове из асинхронной c функции

try {
    let result = await loopCards(cards);
    // do something with result
} catch(error) {
    // handle Error
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...