如何使用承诺使循环不会挂起

How to use promises so that loop doesn't hang

我正在尝试遍历数据库中的记录,以便编译我将写入另一个数据库的数组 (cardsToInsert)。

我被卡住了,因为数组在循环完成之前写入数据库,我知道我需要使用 promises / async 函数来实现我想要的,但我很确定我做错了什么用我的承诺。

该代码运行了几个循环(它进行了大约 6-10 个循环,它应该循环 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
}

如何让它在最终返回 cardsToInsert 之前等待循环完成?

你的 async/await.then 的组合并不是真正的最佳实践

这应该有效,并且 return 一旦填充了 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);

或者如果从异步函数调用

try {
    let result = await loopCards(cards);
    // do something with result
} catch(error) {
    // handle Error
}