Node.js在第一次启动时会给出不可预知的Ajax响应

我使用node.js作为后端和Canjs作为前端库。

节点代码:

var express = require('express'); var app = express(); var http = require("http"); var fs = require("fs"); var cons = require('consolidate') app.configure(function(){ app.engine('html', cons.handlebars); app.set('view engine', 'html'); app.set('views', __dirname) app.use(express.favicon()) app.use(express.logger('dev')) app.use(express.static(__dirname )) app.use(express.bodyParser()) app.use(express.methodOverride()) app.use(express.cookieParser("secret")) app.use(express.session({ secret: 'keyboard cat' })) app.use(app.router) }); app.init = function(){ fs.readFile('./sample.json', 'utf8', function(error, data) { if (error) { throw(error); } else app.set("json", data); })}; app.get('/things', function(req, res){ app.init(); res.set('Content-Type', 'text/json'); res.send(app.get("json")); }); app.get('/things/:id', function(req, res){ app.init(); res.set('Content-Type', 'text/json'); res.send((JSON.parse(app.get("json")))[req.param('id')]); }); app.get('/main.html', function(req, res){ app.init(function(error, data){ if (error) {throw error} res.render('main.html'); }); }); app.listen(3000); 

Can.js代码:

 Todo = can.Model({ findAll: "GET /things", findOne: "GET /things/{id}", },{}); $(document).ready(function(){ Todo.findAll({}, function(todos){ console.log(JSON.stringify(todos)); }) Todo.findOne( { id: 1 }, function( todo ) { console.log( todo ); }) }); 

HTML:

 <script type="text/javascript" charset="utf-8" src="./jquery-1.8.2.js"></script> <script type="text/javascript" charset="utf-8" src="./can.jquery-1.0.7.js"></script> <script type="text/javascript" charset="utf-8" src="./can.fixture.js"></script> <script type="text/javascript" charset="utf-8" src="./master.js"></script> 

JSON:

 {"0":{"id":1,"name":"do the dishes"},"1":{"id":2,"name":"go to dentist"},"2":{"id":3,"name":"go swimming"},"4":{"id":5,"name":"masturbate"}} 

每次启动服务器时,控制台都会为这两个函数(findAll和findOne)findajax GET响应,返回undefined或500错误:

 XHR finished loading: "http://localhost:3000/things". jquery-1.8.2.js:8416 undefined master.js:12 GET http://localhost:3000/things/1 500 (Internal Server Error) jquery-1.8.2.js:8416 XHR finished loading: "http://localhost:3000/things/1". jquery-1.8.2.js:8416 Uncaught TypeError: Function.prototype.apply: Arguments list has wrong type 

但是如果我在这之后刷新页面,这两个函数将正常工作,给:

 XHR finished loading: "http://localhost:3000/things". jquery-1.8.2.js:8416 {"0":{"id":1,"name":"do the dishes"},"1":{"id":2,"name":"go to dentist"},"2":{"id":3,"name":"go swimming"},"4":{"id":5,"name":"masturbate"},"length":0,"_namespace":".observe2"} master.js:12 XHR finished loading: "http://localhost:3000/things/1". jquery-1.8.2.js:8416 Constructor {name: "go to dentist", _data: Object, id: 2, _namespace: ".observe3"} master.js:16 

到底是怎么回事??

问题是你调用app.get("json");app.init (在第一次调用app.init();返回)之后发生的fs.readfilecallback设置其值之前。

你可能应该改变你的代码只调用一次app.init ,并且在工作完成之前不要监听请求。

 app.init = function(callback){ fs.readFile('./sample.json', 'utf8', function(error, data) { if (error) { throw(error); } else { app.set("json", data); callback(); } }); }; ... app.init(function() { app.listen(3000); }); 
Interesting Posts