node.js中的async for loop [英] async for loop in node.js

查看:140
本文介绍了node.js中的async for loop的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是这个node.js的新手..我对这个回调有点困惑。在我的应用程序内部for循环我调用异步函数调用,我想我的问题是在我得到响应之前async call my for loop get loop。

I am new to this node.js ..I am little bit confused about this callback..In my app inside a for loop i am calling a asynchronous function call,i think my problem is that before i am getting response of async call my for loop get looped.

我的代码:

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);
    })

我想在s之后执行循环成功执行1个搜索功能,我想我必须使用async for loop。请指导我解决这个问题。提前谢谢..

I want to execute for loop after successful execution of 1 search function,I think i have to use async for loop.Please guide me to solve this..Thanks in advance..

推荐答案

我已将代码示例缩减为以下行,以便更容易理解概念的解释。

I've reduced your code sample to the following lines to make it easier to understand the explanation of the concept.

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);

上一代码的问题是搜索 function是异步的,所以当循环结束时,没有调用任何回调函数。因此,结果列表为空。

The problem with the previous code is that the search function is asynchronous, so when the loop has ended, none of the callback functions have been called. Consequently, the list of results is empty.

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

To fix the problem, you have to put the code after the loop in the callback function.

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

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

However, since the callback function is called multiple times (once for every iteration), you need to somehow know that all callbacks have been called. To do that, you need to count the number of callbacks, and check whether the number is equal to the number of asynchronous function calls.

获取所有键的列表,使用 Object.keys 。然后,为了遍历此列表,我使用 .forEach (你也可以使用代表(var i = 0,key = keys [i]; i< keys.length; ++ i){..} ,但这可能会产生问题,请参阅内部循环的JavaScript闭包 - 简单实用的例子

To get a list of all keys, use Object.keys. Then, to iterate through this list, I use .forEach (you can also use for (var i = 0, key = keys[i]; i < keys.length; ++i) { .. }, but that could give problems, see JavaScript closure inside loops – simple practical example).

这是一个完整的例子:

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();
            }
        });
    });
}

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

Note: The asynchronous code in the previous example are executed in parallel. If the functions need to be called in a specific order, then you can use recursion to get the desired effect:

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

What I've shown are the concepts, you could use one of the many (third-party) NodeJS modules in your implementation, such as async.

这篇关于node.js中的async for loop的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆