使用 ejs 问题从 mongodb 查看中获取数据

Fetched data from mongodb viewing using ejs trouble

我正在使用 nodejs、mongodb 和 ejs 视图引擎创建求职门户: collection "filters" = 'username' 'tags' collection "alljobs" = 'category' 'jobsdata'

在下面的代码中,我从 "filters" collection 中获取 'tags' 并与 "alljobs" collection 中的所有 'category' 进行比较.然后所有与 'category' 匹配的 'tags' 数组使用 ejs 视图引擎查看它们各自的 'jobsdata'

问题: 代码有效,但在浏览器中我看不到所有匹配类别的相应职位,只能查看一个类别的职位数据。我无法理解问题出在哪里?

代码:

function processRequest(req,res){   
    var tags,data,jobsdata = [];
    var len;
    if(condition)
    {....}
    else{
        var db = new Db('askhere', new Server('localhost', '27017'));
        db.open(function (err, db) {
            db.authenticate('', '', function (err, result) {
                var url = 'mongodb://localhost:27017/askhere';
                client.connect(url, function (err, db) {
                    var col = db.collection('filters');
                    col.find({username:req.session.userName}).toArray(function (err, items) { // find tags of session user from collection filters
                        console.log('items: ' + JSON.stringify(items));
                        items.forEach(function (doc) {
                            tags = doc.tags; //save tags
                        });
                        var col = db.collection('alljobs'); //find all categories jobs matched with tags data in collection alljobs 
                        for(var i=0; i<tags.length;i++){
                            col.find({category:tags[i]}).toArray(function (err, items1) {
                                if (items1 == false) {
                                    res.render('mainqa',{uname:req.session.userName,tags:'No Tags Selected',jobsdata:'No Tags Matched !!!',len:0});
                                }
                                items1.forEach(function (doc1) {
                                    jobsdata = doc1.jobsdata;
                                    var html = ["url : ", "Posted Date : ", "Job Title : ", "Company : ", "Location : "]
                                    for (var i = 0; i < 25; i++) {
                                        for (var j = 0; j < 5; j++) {
                                            data.push(html[j] + jobsdata[i][j]);
                                        } //Nested for loop
                                    }   //for loop covert 2D array in 1D
                                    res.render('mainqa',{uname:req.session.userName,tags:tags,jobsdata:data,len:len});
                                }); //forEach
                            }); //col.find collection=alljobs
                        }   //for loop
                    }); //col.find collection=filters
                }); //client connect
            }); //db.authenticate
        }); //db.open
    }   //else end
}   //function processRequest end

你应该停止使用回调来嵌套多个方法的代码,除非你想以 Callback Hell. Use the async module to simplify this task, in particular you'd need to use async.waterfall() 结束,因为你想 运行 多个任务彼此依赖。

async.waterfall() 方法允许您以滴流方式在函数之间传递值。当您需要前一个函数的结果来执行系列中下一个函数的操作时,它非常方便。

考虑按照此示例进行重组:

var async = require("async"),
    userName = req.session.userName,
    locals = {}, 
    url = 'mongodb://localhost:27017/askhere',
    db = new Db('askhere', new Server('localhost', '27017'));

async.waterfall(
    [
        // Open db
        function(callback) {            
            db.open(function (err, db) {
                if (err) return callback(err);                
                callback(null, db);
            });
        },

        // Authenticate and connect
        function(db, callback) {            
            db.authenticate('', '', function (err, result) {
                if (err) return callback(err); 
                client.connect(url, function (err, res) {
                    if (err) return callback(err);  
                    locals.db = db;
                    callback(null, locals);
                });
            });
        },

        // Query filters collection for tags of session user
        function(arg, callback) {            
            var collection = arg.db.collection("filters");
            collection.find({"username": userName}).toArray(function (err, result) {
                if (err) return callback(err);     
                locals.tags = result.map(function(item){ return item.tags; });              
                callback(null, locals);
            });
        },

        // Query alljobs collection for categories jobs matched with tags data
        function(arg, callback) {            
            var collection = arg.db.collection("alljobs");          
            collection.find({"category": {"$in": arg.tags}}).toArray(function (err, result) {
                if (err) return callback(err);    
                locals.jobsdata = result.map(function (doc){ return doc.jobsdata; });
                callback(null, locals);
            });
        }
    ], function(err, result) {            
        if (err)  { /* handle err */ };
        res.render("mainqa", {
            "uname": userName,
            "tags": result.tags,
            "jobsdata": result.jobsdata
        });
    }); 
);