4

我一辈子都不能让猫鼬在我的快递应用程序中工作。我已经安装了 mongoose,还通过 NPM 安装了 mongodb(mongoose 文档没有说明是否单独需要 mongodb 或如何启动和运行它)。

这是我使用的代码。

    var mongoose = require('mongoose');
    mongoose.connect('mongodb://127.0.0.1/my_database');

    var Schema = mongoose.Schema, ObjectId = Schema.ObjectId;

    var Comments = new Schema({
        title     : String
      , body      : String
      , date      : Date
    });

    var BlogPost = new Schema({
        author    : ObjectId
      , title     : String
      , body      : String
      , date      : Date
      , comments  : [Comments]
      , meta      : {
            votes : Number
          , favs  : Number
        }
    });

    var BlogPost = mongoose.model('BlogPost', BlogPost);
    var post = new BlogPost();
    post.title='blahblah';
    // create a comment
    post.comments.push({ title: 'My comment' });

    post.save(function (err) {
      if(err){
          throw err;
          console.log(err);
      }else{
          console.log('saved!');
      }
    });

有人知道我做错了什么吗?我不明白我是否需要以某种方式单独启动 mongodb(看起来 mongoose.connect 函数启动了 mongodb 服务器对吗?)

但是,当我启动我的应用程序时,什么都没有发生(当我保存测试帖子时,它应该输出错误或保存!到我的控制台,对吧?

无论如何,任何帮助将不胜感激!

谢谢

4

1 回答 1

2

MongoDB 是一个完全独立的服务,因此 nodejs 必须已经在运行才能访问它。

您没有看到任何输出的原因是您的程序在您的帖子完成之前结束,或者在这种情况下,因为它无法到达 MongoDB 而超时。

编辑

如果您仍然好奇为什么在 MongoDB 未运行时没有看到任何输出,请停止 MongoDB,修改您的应用程序以包含:

// exit program in one minute with an error
// cancelled if we can successfully talk to MongoDB
var sentinel = setTimeout(function(){
    throw "failed to connect to MongoDB after one minute!";
}, 60*1000); // 60 seconds

post.save(function (err) {

  clearTimeout(sentinel); // cancel the timeout sentinel

  if(err){
      throw err;
      console.log(err); // won't occur since the throw will end the program
  }else{
      console.log('saved!');
  }
});

process.stdin.resume();  // read from stdin to keep program running

并再次运行它。

重要的是要意识到 nodejs 不像大多数编程环境,因为它在一个事件循环中运行你的程序,只要它有事情要做,它就会运行。如果无事可做,nodejs 将退出。

而且由于您的 post.save() 开始对 MongoDB 进行新的异步调用并立即返回,因此应用程序将立即退出,因为它没有其他事情可做。(在幕后, post.save() 只是将一个新的事件处理程序添加到事件循环中,以等待调用完成。)

为了确保您的程序不会立即退出,我们添加process.stdin.resume()了指示事件循环在每次传递时检查新输入(来自标准输入)的内容,从而有效地使您的程序永远运行。

基于 Nodejs 的网络服务器依赖于相同的机制来连续运行,监视来自网络套接字的输入而不是标准输入。

我怎么强调事件循环概念对 nodejs 编程的重要性都不过分。我估计人们报告的让 nodejs 做他们需要的事情的问题中有 75% 或更多可以归因于不了解事件循环以及它如何影响 nodejs 编程模型!

于 2011-06-13T18:54:27.323 回答