在node.js中异步循环

发布于 2021-02-02 17:18:29

我是这个Node.js的新手..我对此回调有点困惑..在我的应用程序中,我在for循环内调用异步函数调用,我想我的问题是在得到异步调用响应之前,
for循环被循环。

我的代码:

async.forEach(Object.keys(config), function(key, next) {
        search(config[key].query, function(err, result) { // 
        console.log("fffffffffff="+ util.inspect(result))-------- >>>Getting undefined..
            if (err) return next(err) // 
            var json = JSON.stringify({
                "result": result
            });
            results[key] = {
                "result": result
            }
            console.log("rrrrrrrr="+util.inspect(results[key]))
            next() // <---- critical piece.  This is how the forEach knows to continue to the next loop.  Must be called inside search's callback so that it doesn't loop prematurely.                   
        })
    },
    function(err) {
        console.log('iterating done');

         res.writeHead(200, {
        'content-type': 'application/json'
    });
    res.end(JSON.stringify(results));  
    });


}

搜索功能代码:

var matches = [];
    var qrySubString = query.substring(0, 4);
    client.query("select * from xxxxxxxxx where level4 ILIKE '%" + query + "%'", function(err, row1, fields) {
        for (var id in row1.rows) {                
            var match, name;                
            if (query == row1.rows[id].level4) {
                match = true;
                name = row1.rows[id].level4;
            }
            else {
                match = false;
                name = query;
            }
            matches.push({
                "id": id,
                "name": row1.rows[id].level4,
                "score": 100,
                "match": match,
                "type": [{
                    "id": "/people/presidents",
                    "name": "US President"
                }]
            })
        }           
        callback(matches);
    })

我想在成功执行1个搜索功能后执行for循环,我想我必须使用async for loop。请指导我解决此问题。

关注者
0
被浏览
100
1 个回答
  • 面试哥
    面试哥 2021-02-02
    为面试而生,有面试问题,就找面试哥。

    我将您的代码示例简化为以下几行,以使您更容易理解该概念。

    var results = [];
    var config = JSON.parse(queries);
    for (var key in config) {
        var query = config[key].query;
        search(query, function(result) {
            results.push(result);
        });
    }
    res.writeHead( ... );
    res.end(results);
    

    先前代码的问题在于该search函数是异步的,因此在循环结束时,没有调用任何回调函数。因此,的列表results为空。

    要解决此问题,您必须将代码放在循环后的回调函数中。

        search(query, function(result) {
            results.push(result);
            // Put res.writeHead( ... ) and res.end(results) here
        });
    

    但是,由于多次调用了回调函数(每次迭代一次),因此您需要以某种方式知道所有回调都已被调用。为此,您需要计算回调的数量,并检查该数量是否等于异步函数调用的数量。

    这是一个完整的示例:

    var results = [];
    var config = JSON.parse(queries);
    var onComplete = function() {
        res.writeHead( ... );
        res.end(results);
    };
    var keys = Object.keys(config);
    var tasksToGo = keys.length;
    if (tasksToGo === 0) {
       onComplete();
    } else {
        // There is at least one element, so the callback will be called.
        keys.forEach(function(key) {
            var query = config[key].query;
            search(query, function(result) {
                results.push(result);
                if (--tasksToGo === 0) {
                    // No tasks left, good to go
                    onComplete();
                }
            });
        });
    }
    

    注意:上一个示例中的异步代码是并行执行的。如果需要按特定顺序调用函数,则可以使用递归获得所需的效果:

    var results = [];
    var config = JSON.parse(queries);
    var keys = Object.keys(config);
    (function next(index) {
        if (index === keys.length) { // No items left
            res.writeHead( ... );
            res.end(results);
            return;
        }
        var key = keys[index];
        var query = config[key].query;
        search(query, function(result) {
            results.push(result);
            next(index + 1);
        });
    })(0);
    

    我所展示的是概念,您可以在实现中使用许多(第三方)NodeJS模块之一,例如async。



推荐阅读
知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看