我开始在node.js中编写一个服务器,并想知道我是否正确地做事......
基本上我的结构类似于以下伪代码:
function processStatus(file, data, status) {
...
}
function gotDBInfo(dbInfo) {
var myFile = dbInfo.file;
function gotFileInfo(fileInfo) {
var contents = fileInfo.contents;
function sentMessage(status) {
processStatus(myFile, contents, status);
}
sendMessage(myFile.name + contents, sentMessage);
}
checkFile(myFile, gotFileInfo);
}
checkDB(query, gotDBInfo);
一般来说,我想知道这是否是编写node.js的正确方法,更具体地说:
1)VM是否足够智能,可以在每次回调之间“同时”(即切换上下文)运行,而不会被大量连接的客户端挂起?
2)当运行垃圾收集时,如果最后一个回调(processStatus)完成,它会完全清除内存吗?
答案 0 :(得分:2)
Node.js基于事件,所有代码基本上都是事件处理程序。 V8引擎将执行处理程序中的任何同步代码,然后处理下一个事件。
异步调用(网络/文件IO)会将事件发布到另一个线程来执行阻塞IO(即 libev
libeio
AFAIK,我可能错了这个)。您的应用程序可以处理其他客户端。 IO任务完成后,将触发一个事件并调用您的回调函数。
以下是异步调用流程的示例,模拟处理客户端请求的Node应用程序:
onRequest(req, res) {
// we have to do some IO and CPU intensive task before responding the client
asyncCall(function callback1() {
// callback1() trigger after asyncCall() done it's part
// *note that some other code might have been executed in between*
moreAsyncCall(function callback2(data) {
// callback2() trigger after moreAsyncCall() done it's part
// note that some other code might have been executed in between
// res is in scope thanks to closure
res.end(data);
// callback2() returns here, Node can execute other code
// the client should receive a response
// the TCP connection may be kept alive though
});
// callback1() returns here, Node can execute other code
// we could have done the processing of asyncCall() synchronously
// in callback1(), but that would block for too long
// so we used moreAsyncCall() to *yield to other code*
// this is kind of like cooperative scheduling
});
// tasks are scheduled by calling asyncCall()
// onRequest() returns here, Node can execute other code
}
当V8没有足够的内存时,它会进行垃圾回收。它知道实时JavaScript对象是否可以访问一块内存。我不确定它是否会在达到功能结束后积极清理内存。
参考文献:
This Google I/O演讲讨论了Chrome的GC机制(因此是V8)。
http://platformjs.wordpress.com/2010/11/24/node-js-under-the-hood/