2

我正在使用运行在 Node.js 平台上的 JavaScript 构建一个简单的服务器。服务器接受 JavaScript 对象,解析它们,并根据它找到的内容执行命令;相当简单的东西。我称这些为对象Envelopes(因为您在现实生活中打开信封并根据他们所说的做事。明白吗?我很聪明。)。

我有 3 个文件,分别称为:server.jsenvelope.jsuser-handler.js. 在我的测试中,用户发送一个“用户”信封供服务器解析,最终服务器创建一个新用户并将它们添加到我在本地设置的 MongoDB 实例中。

但是,在 中user-handler.js,我遇到了一个奇怪的错误:TypeError: object is not a function. 我不知道为什么会收到此错误,因为该Envelope对象肯定是正确导入的。您将在下面找到有问题的 3 个文件。非常感谢任何和所有答案!

编辑:为澄清起见,这是我在运行测试时得到的确切堆栈跟踪(我也包括在内):

Server listening on port 31337
Accepted input from user...
Opened up the envelope...
[Function: Envelope]
Envelope verified successfully
It's a 'user' command...
Starting to parse the envelope...
Going to create a new user...
Now to save new user...

/home/ME/PROJECT/lib/user-handler.js:52
      console.log(new Envelope({
                  ^
TypeError: object is not a function
    at Object.module.exports.parseEnvelope (/home/ME/PROJECT/lib/user-handler.js:52:19)
    at Envelope.open (/home/ME/PROJECT/lib/envelope.js:34:28)
    at Socket.<anonymous> (/home/ME/PROJECT/lib/server.js:22:22)
    at Socket.EventEmitter.emit (events.js:95:17)
    at Socket.<anonymous> (_stream_readable.js:720:14)
    at Socket.EventEmitter.emit (events.js:92:17)
    at emitReadable_ (_stream_readable.js:392:10)
    at emitReadable (_stream_readable.js:388:5)
    at readableAddChunk (_stream_readable.js:150:9)
    at Socket.Readable.push (_stream_readable.js:113:10)

服务器.js

"use strict";

var net = require("net")
  , mongoose = require("mongoose")
  , dbConf = require("../conf")
  , Envelope = require("./envelope")
  , UserHandler = require("./user-handler")
  , uri, db, server;

uri = (dbConf.uri || "mongodb://localhost") // URI
  + (":" + (dbConf.port || 27017) + "/") // Port
  + (dbConf.db || "DATABASE"); // Database
db = mongoose.connect(uri);

server = net.createServer(function(socket) {
  socket.on("data", function(data) {
    var input, output;

    //try {
      input = new Envelope(JSON.parse(data.toString()));
      console.log("Accepted input from user...");
      output = input.open();
      console.log("And the output is: ");
    /*} catch (error) {
      var errorString = String(error).split(": ");
      output = new Envelope({
        header: {
          type: "error"
        },
        body: {
          errorType: errorString[0],
          errorMessage: errorString[1]
        }
      });
    }*/

    console.log(JSON.stringify(output));
  });
});

server.listen(31337, function() {
  console.log("Server listening on port 31337"); 
});

信封.js

"use strict";

var userHandler = require("./user-handler");

var Envelope = function Envelope(data) {
  for (var key in data) {
    this[key] = data[key];
  }
};

Envelope.prototype = {
  constructor: Envelope,

  verify: function() {
    console.log(this.constructor);

    if (this.header && this.header.type && this.body) {
      console.log("Envelope verified successfully");
      return true;
    } else {
      console.log("Envelope did not verify successfully");
      return false;
    }
  },

  open: function() {
    var self = this;

    console.log("Opened up the envelope...");
    if (self.verify()) {
      switch (self.header.type) {
      case "user":
        console.log("It's a 'user' command...");
        return userHandler.parseEnvelope(self);
        break;

      default:
        return new Envelope({
          header: {
            type: "empty"
          }
        });
      }
    } else {
      return new Envelope({
        header: {
          type: "error"
        },
        body: {
          errorType: "MissingDataError",
          errorMessage: "Missing either: header, body, or header.type"
        }
      });
    }
  }
};

module.exports = Envelope;

用户处理程序.js

"use strict";

var User = require("../models/user")
  , Envelope = require("./envelope");

module.exports = {
  parseEnvelope: function(env) {
    var header = env.header;
    var body = env.body;

    console.log("Starting to parse the envelope...");
    switch (header.method) {
    case "create":
      console.log("Going to create a new user...");
      var newName = body.name || {
        first: "",
        last: ""
      };

      var newUser = new User({
        username: body.username,
        password: body.password,
        name: newName,
        email: body.email || ""
      });

      console.log("Now to save new user...");
      /*newUser.save(function(err) {
        if (err) {
          console.log("Ruh roh, there was an error...");
          console.log(String(err));
        } else {
          console.log("New user saved successfully to the database...");
          return newUser;
        }
      });*/
      /*var response = new Envelope({
        header: {
          type: "response",
          requestType: "user",
          requestMethod: "create"
        },
        body: {
          _id: newUser._id,
          username: newUser.username,
          password: newUser.password,
          name: newUser.name,
          email: newUser.email
        }
      });*/

      console.log(new Envelope({
        test: "Hello, world!"
      }));

      //console.log(response);
      break;

    default:
      return new Envelope({
        header: {
          type: "error"
        },
        body: {
          error: "MissingHeaderMethodError",
          errorMessage: "Missing header parameter: method"
        }
      });
      break;
    }
  }
};

测试/user.js

"use strict";

var net = require("net")
  , client;

client = net.connect({host: "localhost", port: 31337}, function() {
  client.end(JSON.stringify(
    {
    "header": {
      "type": "user",
      "method": "create"
    },
    "body": {
      "username": "john_doe",
      "password": "password1",
    }
    }
  ));
});
4

1 回答 1

2

问题可能是您有循环导入。您的信封导入用户处理程序,用户处理程序导入信封。由于信封“只是”一个信封,它可能不知道用户处理程序。因此,您可以通过以下方式对其进行重构:

信封.js

open: function(callback) {
var self = this;

console.log("Opened up the envelope...");
if (self.verify()) {
  switch (self.header.type) {
  case "user":
    console.log("It's a 'user' command...");
    return callback(self);
    break;

  default:
    return new Envelope({
      header: {
        type: "empty"
      }
    });
  }
} else {
  return new Envelope({
    header: {
      type: "error"
    },
    body: {
      errorType: "MissingDataError",
      errorMessage: "Missing either: header, body, or header.type"
    }
  });
}
}

服务器.js

output = input.open(UserHandler.parseEnvelope);

现在你不需要在你的 Envelope.js 中导入你的 user-handler.js 并且一切都应该顺利进行。

于 2013-05-11T16:56:09.780 回答