如何在递增循环之前等待for循环内的异步过程完成

时间:2018-08-10 05:54:08

标签: node.js mongodb async-await

我需要遍历一个数组。每次迭代时,我需要更新数据库。我需要等待第一次更新完成,然后再进行第二次更新。 在搜索了几个答案之后,我发现了ES2017的ASYNC / AWAIT功能。但是,到目前为止,我还无法实现它。更新是随机发生的,而不是按顺序进行。请让我知道在这种情况下如何实施ASYNC / AWAIT 这是我的代码段:

function findRecipe(product, qty) {
    return new Promise((resolve, reject) => {
        Recipe.findOne({
            product: product
        }, (err, recipe) => {
            if (err) {
                reject(err)
            } else {
                for (let i = 0; i < recipe.items.length; i++) {

                    Item.findOne({
                        name: recipe.items[i].name
                    }, (err, item) => {
                        if (err) {
                            reject(err)
                        } else {
                            var lessAmt = recipe.quantities[i] * qty;
                            item.stock -= lessAmt;
                            item.save((err, item) => {
                                if (err) {
                                    console.log(err)
                                } else {
                                    resolve(item)
                                }
                            })
                        }
                    })
                }
            }
        })
    });
}

for (let i = 0; i < bill.product.length; i++) {
    //Calling function for updates for each item
    findRecipe(bill.product[i], bill.qty[i])
}

3 个答案:

答案 0 :(得分:1)

您似乎快到了,只需将循环包装在函数中并使其异步即可。

async function updateAllRecipe(){
 for(let i=0;i<bill.product.length;i++){
 //Calling function for updates for each item
 await findRecipe(bill.product[i],bill.qty[i])
 }
}

但是很认真,我认为您可以使用Promise.All在这里利用并行性。在查询下一个findRecipe方法之前,是否真的需要等待配方完成?如果不使用promise.all,它的执行速度会更快

答案 1 :(得分:0)

一旦您知道Node.js异步性质的基本概念,异步等待就很容易实现,我在这里使用了for...of循环,它也可以异步工作。

//Async function to perform database updates

async function findRecipe(product, qty) {
try {
    let recipe = await Recipe.findOne({ product: product });
    let i = 0;
    for (itemObj of recipe.items) {
        let item = await Item.findOne({ name: itemObj.name });
        var lessAmt = recipe.quantities[i] * qty;
        item.stock -= lessAmt;
        let updatedItem = await item.save();
        i++;
    }
    return true;
}
catch (err) {
    return err;
 }
}



async function someasyncFunction() {

    for (let i = 0; i < bill.product.length; i++) {
        //Calling function for updates for each item
        await findRecipe(bill.product[i], bill.qty[i])
    }
}

答案 2 :(得分:0)

使用Promise.all并并行启动过程。它将提高API的性能。

  async function findRecipe(product, qty) {
        try {
            let recipe = await Recipe.findOne({
                product: product
            });
            const items = await Promise.all(recipe.items.map(itemObj => Item.findOne({
                name: itemObj.name
            })));

            const items = await Promise.all(items.map((item, i) => {
                var lessAmt = recipe.quantities[i] * qty;
                item.stock -= lessAmt;
                return item.save();
            }));
            return true;
        } catch (err) {
            return err;
        }
    }



    async function someasyncFunction() {
        await Prmise.all(bill.product.map((product, i) => findRecipe(product, bill.qty[i])));
    }