连接到MongoDB中的2个集合并使用express作为路由

时间:2013-12-02 03:05:19

标签: mongodb collections express

//creating a route for http://127.0.0.1:8080/Work
app.get('/Work', function(req, res){

        //connect to my first collection
       db.collection('my-collection1').find().each( function (err,doc) {

            //if there's an error 
             if(err) throw err;

            //if there is no more docs 
            if (!doc) {
                console.dir("No document found");
                return db.close();
                //return;
            }

        //...do stuff here to your docs here to get a value for x

        });

        //write to the Work.html file in your/views directory  and pass it the variable x
        return res.render('Work', { "x" : x });

        //connect to my 2nd collection
        db.collection('my-collection2').find().each( function (err,doc) {

            //if there's an error 
             if(err) throw err;

            //if there is no more docs 
            if (!doc) {
                console.dir("No document found");
                return db.close();
                //return;
            }

            //...do stuff here to your docs here to get a value for y

        });

        //write to the Work.html file in your/views directory  and pass it the variable x
        return res.render('Work', { "y" : y });

    });

使用上面的代码,我要做的是连接到MongoDB中的2个集合,并使用express框架将它们渲染到我的/ views /目录中的网页文件。

我的views目录中的html文件如下所示:

<html>
<h6>Hello there.</h6>
<h6>Value of x is:  {{x}} </h6>
<h6>Value of y is: {{y}} </h6>
<html>

现在我的问题是要显示x和y。现在这可能是由于我对回调和异步函数缺乏了解,我稍微理解了这一点。

基于我提供的内容,有人可以建议我如何实现我想要的功能,同时还可以解释回调和异步功能?也许我的方法是完全错误的连接到这样的2个集合? tks

注意:这些是自己工作的(如果我在自己的单独页面上显示它们),这里我试图将x和y放在一起并显示在一页上。

1 个答案:

答案 0 :(得分:0)

第一个问题是,只要您致电return res.render('Work', { "x" : x });,您的功能就会终止,而且计算y的代码部分永远不会被执行。

我还假设您在x函数的范围之上声明了变量yGET,并且存储了值?如果没有,你应该这样做,以使他们的范围更明确。

你也在调用db.close(),这不是必需的,因为你只是停留在同一个数据库中而只是切换集合,所以从性能的角度来看,你只想继续使用相同的连接计算(连接池将在引擎盖下进行)。

您的代码正在执行的异步说明:

将这些问题排除在外,调用的异步性质意味着你的函数(计算x的函数和计算y的函数)是并行执行的(即同时执行),并且因为你如果没有res.renderx,我们不知道在y拨打render之前哪个完整。 200 OK函数只能在Express中调用一次,因为在调用它时会将结果发送回用户的浏览器并发送x HTTP响应,并结束与Node webserver的连接。

因此,您的基本问题归结为需要保证已完成计算完成yx,然后仅将一个响应发送回网络浏览器。

您有两种选择来解决这个问题:

  1. 将它们转换为串行函数调用 - 即调用计算y的函数,等待它完成,然后再调用计算return res.render('Work', { "x" : x, "y" : y });的函数,然后渲染结果。这就是回调的用武之地。请注意,这种方法可能比以异步方式进行两种计算要慢,因为您迫使第二步等待可能耗费时间的过程才能完成甚至可以启动。< / p>

  2. 异步运行两个计算,当它们终止时,它可以检查另一个计算是否也已完成。无论哪一个完成第二个,都会调用x,并知道yy已填充了您想要的结果。你需要执行这个wat

  3. 选项1 使用回调看起来像这样(请注意,x的计算仅在没有其他文档要处理以计算//creating a route for http://127.0.0.1:8080/Work app.get('/Work', function(req, res){ //connect to my first collection db.collection('my-collection1').find().each( function (err,doc) { if(err) throw err; //...do stuff here to your docs here to get a value for x //once there are no more docs, initiate the calculation for y if (!doc) { console.dir("No document found"); db.collection('my-collection2').find().each( function (err,doc) { if(err) throw err; //...do stuff here to your docs here to get a value for y //if there is no more docs, then we know that both x and y have been calculated if (!doc) { console.dir("No document found"); res.render('Work', { "x" : x, "y" : y }); } } } }); }); 时启动:)< / p>

    x

    还有各种各样的框架允许您在节点中以同步方式链接异步调用 - 检查streamline.js,这允许您使用下划线字符作为回调来更干净地进行链式方法,但是即使你使用这样一个库,它几乎可以转化为我上面的代码在幕后所做的事情。

    选项2 (我的首选选项,因为它可能是更好的性能)只需通过检查计数器来检查y//creating a route for http://127.0.0.1:8080/Work app.get('/Work', function(req, res){ var counter = 0; //connect to my first collection db.collection('my-collection1').find().each( function (err,doc) { if(err) throw err; //...do stuff here to your docs here to get a value for x //once there are no more docs, add one to the counter if (!doc) { console.dir("No document found"); counter++; if (counter == 2) { res.render('Work', { "x" : x, "y" : y }); } } }); db.collection('my-collection2').find().each( function (err,doc) { if(err) throw err; //...do stuff here to your docs here to get a value for x //once there are no more docs, add one to the counter if (!doc) { console.dir("No document found"); counter++; if (counter == 2) { res.render('Work', { "x" : x, "y" : y }); } } }); }); 的计算是否已完成:< / p>

    res.render

    所以基本上,你可以并行执行两个计算,然后以第二个结束时调用{{1}}并发回响应。

    请注意,我实际上没有测试上面的代码片段,但他们应该给你这个想法。