Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/404.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/38.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在Express.js和mongoose中为每个循环编写异步循环?_Javascript_Node.js_Mongodb_Mongoose - Fatal编程技术网

Javascript 如何在Express.js和mongoose中为每个循环编写异步循环?

Javascript 如何在Express.js和mongoose中为每个循环编写异步循环?,javascript,node.js,mongodb,mongoose,Javascript,Node.js,Mongodb,Mongoose,我有一个从MongoDB返回项目数组的函数: var getBooks = function(callback){ Comment.distinct("doc", function(err, docs){ callback(docs); } }); }; 现在,对于文档中返回的每个项目,我想执行另一个mongoose查询,收集特定字段的计数,将它们全部收集到counts对象中,最后将其传递到res.render: getBooks(fun

我有一个从MongoDB返回项目数组的函数:

var getBooks = function(callback){
    Comment.distinct("doc", function(err, docs){
            callback(docs);
        }
    });
};
现在,对于文档中返回的每个项目,我想执行另一个mongoose查询,收集特定字段的计数,将它们全部收集到
counts
对象中,最后将其传递到
res.render

getBooks(function(docs){
    var counts = {};
    docs.forEach(function(entry){
        getAllCount(entry, ...){};
    });      
});

如果我将
res.render
放在
forEach
循环之后,它将在计数查询完成之前执行。但是,如果我将它包括在循环中,它将为每个条目执行。这样做的正确方法是什么?

事实上,第一项上的getAllCount必须回调第二项上的getAllCount

双向:您可以使用框架,如async:

或者自己创建回调链。第一次写作很有趣

编辑 我们的目标是建立一个像我们写的那样进行的机制

getAllCountFor(1, function(err1, result1) {
    getAllCountFor(2, function(err2, result2) {
        ...
            getAllCountFor(N, function(errN, resultN) {
                res.sender tout ca tout ca
            });
    });
});

这就是您将使用async使用序列格式构造的内容。

事实上,第一项上的getAllCount必须在第二项上回调getAllCount

双向:您可以使用框架,如async:

或者自己创建回调链。第一次写作很有趣

编辑 我们的目标是建立一个像我们写的那样进行的机制

getAllCountFor(1, function(err1, result1) {
    getAllCountFor(2, function(err2, result2) {
        ...
            getAllCountFor(N, function(errN, resultN) {
                res.sender tout ca tout ca
            });
    });
});

这就是您将使用async构建的,使用序列格式。

forEach
可能不是您在这里的最佳选择,除非您希望对
getAllCount
的所有调用都并行进行(我不知道您可能会这样做,或者在这方面,节点默认情况下仍然是单线程的,不是吗?)。相反,只需保留一个索引并对
文档中的每个条目重复调用,直到完成为止,这似乎更好。例如:

getBooks(function(docs){
    var counts = {},
        index = 0,
        entry;

    loop();

    function loop() {
        if (index < docs.length) {
            entry = docs[index++];
            getAllCount(entry, gotCount);
        }
        else {
            // Done, call `res.render` with the result
        }
    }
    function gotCount(count) {
        // ...store the count, it relates to `entry`...

        // And loop
        loop();
    }
});

forEach
可能不是您在这里的最佳选择,除非您希望对
getAllCount
的所有调用都并行进行(我不知道您是否希望这样做,或者在这方面,默认情况下节点仍然是单线程的,不是吗?)。相反,只需保留一个索引并对
文档中的每个条目重复调用,直到完成为止,这似乎更好。例如:

getBooks(function(docs){
    var counts = {},
        index = 0,
        entry;

    loop();

    function loop() {
        if (index < docs.length) {
            entry = docs[index++];
            getAllCount(entry, gotCount);
        }
        else {
            // Done, call `res.render` with the result
        }
    }
    function gotCount(count) {
        // ...store the count, it relates to `entry`...

        // And loop
        loop();
    }
});

我建议使用流行的NodeJS包。这比做工作/计数容易得多,最终的错误处理将需要答案

特别是,我建议考虑每一个
():

或者您可以使用
map
():


如果同时请求太多,可以使用
mapLimit
eachLimit
函数来限制同步异步mongoose请求的数量。

我建议使用流行的NodeJS包。这比做工作/计数容易得多,最终的错误处理将需要答案

特别是,我建议考虑每一个
():

或者您可以使用
map
():


如果同时请求太多,可以使用
mapLimit
eachLimit
函数来限制同步异步mongoose请求的数量。

但即使我要编写长回调链,我在哪里包括
res.render
?如果它位于回调链的末尾,它将对循环中的每个条目执行,对吗?但是即使我要编写长回调链,我在哪里包括
res.render
?如果它位于回调链的末尾,它将对循环中的每个条目执行,对吗?很好的解释…:)很好,我喜欢第二种方法,即跟踪是否所有事情都已处理。在这种情况下,使用
async.each
方法是否会更好,以便并行处理内容?@mart1n:我对Node了解得不够(有一段时间没有使用它了,事情已经发生了变化)来回答这个问题。我最后一次听说,Node使用了一个线程和一个分派循环,这与浏览器对主JavaScript线程的处理方式非常相似。(例如,当不使用web workers时。)因此,在异步时,节点本身是单线程的。如果这一点发生了变化,是的,您将需要使用任何涉及的语义来获得适当的并行性。很好的解释…:)很好,我喜欢第二种方法,即跟踪是否所有事情都已处理。在这种情况下,使用
async.each
方法是否会更好,以便并行处理内容?@mart1n:我对Node了解得不够(有一段时间没有使用它了,事情已经发生了变化)来回答这个问题。我最后一次听说,Node使用了一个线程和一个分派循环,这与浏览器对主JavaScript线程的处理方式非常相似。(例如,当不使用web workers时。)因此,在异步时,节点本身是单线程的。如果这一点发生了变化,是的,您将希望使用任何涉及的语义来获得适当的并行性。向下投票按钮用于不有用的答案,而不是不使用首选方法的答案。向下投票按钮用于不有用的答案,而不是不使用首选方法的答案。
getBooks(function(docs){
    async.map(docs, function(doc, transformed){
        getAllCount(entry, ...);         
        // call transformed(null, theCount);
        // for each document (or transformed(err); if there was an error); 
    }, function(err, results) {
       // all are complete (or an error occurred)
       // you can access results here, which contains the count value
       // returned by calling: transformed(null, ###) in the map function
       res.render(...);
    });      
});