node.js 中的异步 for 循环 [英] async for loop in node.js

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

问题描述

我是这个 node.js 的新手..我对这个回调有点困惑..在我的应用程序中的 for 循环中,我正在调用一个异步函数调用,我认为我的问题是在我得到响应之前异步调用我的 for 循环得到循环.

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

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

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

前面代码的问题是search 函数是异步的,所以当循环结束时,没有调用任何回调函数.因此,results 的列表是空的.

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(你也可以使用 for (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 模块之一,例如 异步.

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 中的异步 for 循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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