首页 > 解决方案 > 异步循环没有等待

问题描述

我正在使用 node-async-loop 进行异步编程

var array = ['item0', 'item1', 'item2'];
asyncLoop(array, function (item, next)
{
    do.some.action(item, function (err)
    {
        if (err)
        {
            next(err);
            return;
        }
 
        next();
    });
}, function (err)
{
    if (err)
    {
        console.error('Error: ' + err.message);
        return;
    }
 
    console.log('Finished!');
});

像这样,我使用三个异步循环,一比一。我只想在第三个内部循环结束后发送响应。我该怎么做?这是节点异步循环的链接(https://www.npmjs.com/package/node-async-loop

这是我写的代码,但是当最后一个循环完成时我想响应它说可以在发送给客户端后设置标题。同样在控制台日志中,每当数据来自查询时,我都会获取数据。

const id = req.params.id;
    finalData = [];
    tb_user.findOne({ where: { id: id } }).then((userRiverSys, err) => {
        if (userRiverSys) {
            // console.log(userRiverSys.regionJson)
            asyncLoop(userRiverSys.regionJson, function (item, next) {
                // console.log("item", item);
                tb_riverSystems.findAll(
                    {
                        where: { regionId: item.id }
                    }).then((findriverSys, err) => {
                        if (err) {
                            next(err);
                            return;
                        }
                        // console.log("findriverSys", findriverSys);
                        if (findriverSys) {
                            asyncLoop(findriverSys, function (item1, next1) {
                                if (err) {
                                    next(err);
                                    return;
                                }
                                // console.log("item1", item1.dataValues);
                                tb_facilities.findAll(
                                    {
                                        where: { riverSystemId: item1.dataValues.id }
                                    }).then((findFacilities) => {
                                        if (findFacilities) {
                                            // console.log("findFacilities", findFacilities[0].dataValues.name);
                                            asyncLoop(findFacilities, function (item2, next2) {
                                                if (err) {
                                                    next(err);
                                                    return;
                                                }
                                                tb_userAccess.findAll(
                                                    {
                                                        where: { facilityId: item2.dataValues.id }
                                                    }).then((userAccessFacilities, err) => {
                                                        // console.log("userAccessFacilities", userAccessFacilities[0].dataValues);
                                                        // var i = 0;
                                                        asyncLoop(userAccessFacilities, function (item3, next3) {
                                                            finalData.push({
                                                                UserId: item3.userid,
                                                                facilityId: item3.facilityId,
                                                            })

                                                            next3();
                                                        },
                                                            function (err) {
                                                                if (err) {
                                                                    console.error('Error: ' + err.message);
                                                                    return;
                                                                }
                                                                // i++;
                                                                // console.log('Finished!!!!');
                                                                // if (userAccessFacilities.length === i) {
                                                                //  console.log("finalData", i);
                                                                //  // res.json({"status":"true", "message":"update OrgChallenge"})
                                                                //    }
                                                            })
                                                            return  res.json({"status":"true", "message":"update OrgChallenge"})
                                                        
                                                            // console.log("finalData", finalData);

                                                    })
                                                next2();
                                            }, function (err) {
                                                if (err) {
                                                    console.error('Error: ' + err.message);
                                                    return;
                                                }
                                                console.log('Finished!!!');
                                            });
                                        }
                                    });
                                next1();
                            }, function (err) {
                                if (err) {
                                    console.error('Error: ' + err.message);
                                    return;
                                }
                                console.log('Finished!!');
                            });
                        }
                    });
                next();
            }, function (err) {
                if (err) {
                    console.error('Error: ' + err.message);
                    return;
                }
                console.log('Finished!');
            });

        } else {
            console.log("err3", err)
        }
    })

标签: node.jsarraysasynchronous

解决方案


如果您承诺您的异步操作(因此它返回一个承诺),那么您可以只使用常规for循环,async/await并且不需要第 3 方库来对您的异步循环进行排序。这是现代 Javascript:

const { promisify } = require('util');
do.some.actionP = promisify(do.some.action);

async function someFunction() {
    const array = ['item0', 'item1', 'item2'];
    for (let item of array) {
        let result = await do.some.actionP(item);
        // do something with result here
    }
    return someFinalResult;
}

someFunction().then(result => {
   console.log(result);
}).catch(err => {
   console.log(err);
});

仅供参考,在实际代码中,许多(甚至大多数)异步操作现在已经提供了其 API 的承诺版本,因此通常您甚至不需要再执行承诺步骤。例如,几乎所有数据库都已经提供了一个可以直接使用的 Promise 接口。


推荐阅读