使用异步调用在for循环中构建数组

时间:2017-01-29 09:10:12

标签: javascript node.js api

我是JavaScript的新手,我尝试按以下方式执行操作。我想迭代一个列表,并进行依赖于列表中项目的数据库调用。显然,因为调用是异步的,所以当for循环结束时,没有返回任何调用,因此列表为空。

在c#中,我可以等待数据库调用,这样可以正常工作。我试图在javascript中找到类似的方法,但我没有太多运气

exports.methodName = (req, res) => {

    var itemsToReturn = []

    for (let item of list) {
        db.all(sql), (err, rows) => {
            itemsToReturn.push(rows)
        }
    }

    res.json(itemsToReturn )
}

我使用SQLite作为我的数据库

1 个答案:

答案 0 :(得分:1)

在Javascript中执行此操作的现代方法是使用或创建db.all()的promise接口(而不是您显示的回调接口),然后在承诺数组上使用Promise.all()当所有异步操作完成时。你没有说你的数据库是什么,所以我们不能提供任何关于你的数据库是否已经有一个promise接口的帮助(很多人现在都这样做。)

这是手动的做事方式,假设list是一个数组:

exports.methodName = (req, res) => {

    let itemsToReturn = [];
    let cntr = 0;
    for (let [index, item] of list.entries()) {
        db.all(sql), (err, rows) => {
            if (err) {
               // insert error handling here
            } else {
                itemsToReturn[index] = rows;
                ++cntr;
                if (cntr === list.length) {
                    res.json(itemsToReturn);
                }
            }
        }
    }
}

假设你有一个名为db.allPromise()的数据库的promise接口,你可以这样做:

exports.methodName = (req, res) => {

    Promise.all(list.map(item => {
        return db.all(someSql);
    })).then(results => {
        res.json(results);
    }).catch(err => {
        res.sendStatus(500);
    });
}