该文章为网络课 Introduction to MongoDB using the MEAN Stack学习笔记。
1. MEAN Stack
The MEAN stack is MongoDB, Express.js, Angular, and Node.js. Because all components of the MEAN stack support programs are written in JavaScript, MEAN applications can be written in one language for both server-side and client-side execution environments.
MongoDB:数据库
Express.js:Web app
Angular.js:前端
Node.js:后端
2. MongoDB
2.1 基本
属于NoSQL的一种,存储的是一种类JSON文件,即BSON(Binary JSON),包含JSON并不限于JSON。
2.2 命令
- mongod -> 启动数据库服务器
mongod --dbpath ~/data/db/
- mongo -> 启动数据库shell界面
mongo
待学习...
3. npm
Node Package Manager是专门用来管理node.js项目的软件。设计者通过定义一个package.json文件,就可以管理好许多关于项目的信息,包括项目基本信息(版本,作者,描述),项目依赖的包信息,项目测试等等。
比如,举例如下的package.json
{
"scripts": {
"test": "mocha test.js",
"test-kitten": "mocha -R nyan test.js",
"watch": "gulp watch"
},
"dependencies": {
"underscore" : "1.5.2",
"mongodb" : "2.0.35",
"mocha" : "2.2.4"
},
"devDependencies": {
"gulp": "3.8.11",
"gulp-mocha": "2.0.1",
"mocha": "2.2.4"
}
}
3.1 "dependencies"
通俗来讲,就是一个定义了项目中要依赖的其他package。npm拥有许多开源的包,可供设计者使用,大大简化了设计。
设计者只需要在package.json中列出所要用的包以及它们对应的版本, 然后在命令行中执行:
npm install
项目所需要的包即可下载到本地,项目中即可通过require()
语句来引用要用的包。
var mongodb = require('mongodb');
var assert = require('assert'); //node.js内置包
3.1 “scripts”
通过在此定义一些npm的命令来提高开发的效率。
比如:
npm test
相当于执行node_modules/.bin/mocha test.js
,该mocha
包用来对项目进行测试。
test.js
文件中定义了一些测试程序:
var assert = require('assert'); /引用build-in的评估包
describe('my feature', function() { //定义一个名为'my feature'的testcase
it('works', function() {
assert.equal('A', 'A'); //评估'A'是否等于'A'
});
it('fails gracefully', function() {
assert.throws(function() { //如果assert的评估有错误
throw 'Error!';
});
});
});
describe('my other feature', function() {
it('async', function(done) {
setTimeout(function() {
done();
}, 25);
});
});
npm run watch
(不要忘记run)相当执行./node_modules/.bin/gulp watch
,该gulp
包下的gulp-mocha
plugin包用来对mocha测试进行封装。此外,更强大的地方在于还可以进行自动测试,当它运行时,自动检测项目中的文件的改动,一旦有改动,自动运行测试。需要定义一个如下的gulpfile.js
文件
var gulp = require('gulp'); //引用gulp core
var mocha = require('gulp-mocha'); //引用gulp的mocha plugin
gulp.task('test', function() { //定义一个名叫'test'的gulp测试任务
gulp.
src('./test.js'). //该测试任务包含test.js中的所有testcase
pipe(mocha()). //在此体现对mocha的封装:实际上调用mocha包来测试
on('error', function(err) {
this.emit('end');
});
});
// watching specific file's changing
gulp.task('watch', function() { //定义一个名叫watch的gulp自动测试任务
gulp.watch('./*.js', ['test']); //对所有.js文件的改动进行检测,一旦有改动,执行之前定义的名为'test'的gulp任务
});
4. node.js
4.1 与mongoDB的连接
var mongodb = require('mongodb');
var uri = 'mongodb://localhost:27017/example';
//.MongoClient.connect is used for connecting to the database
mongodb.MongoClient.connect(uri, function(error, db) {
if (error) {
console.log(error);
process.exit(1);
}
//.collection is used for connectting a collection
//.insert is used for inserting data
db.collection('sample').insert({ x: 1 }, function(error, result) {
if (error) {
console.log(error);
process.exit(1);
}
// .find() need to be chained with .toArray() to get the actual data
// using .find() to qeury documents whose attr "attrName" is "abc"
db.collection('sample').find(attrName : "abc").toArray(function(error, docs) {
if (error) {
console.log(error);
process.exit(1);
}
console.log('Found docs:');
docs.forEach(function(doc) {
console.log(JSON.stringify(doc));
});
process.exit(0);
});
});
});
4.2 关于Node.js的concurrency与event loop
其实这也是javascript不同于java或c++等语言的方面。
javascript支持一种叫做call back function的函数参数形式。该function只有在函数的操作被正常执行后才执行,否者常常有对错误的处理。这个性质也叫作asynchronous。
可以理解为,javascript的各种函数是在一个叫event loop的函数里执行,如下图:
之所以这么说,是因为javascript的解释器是在一个loop里不断运行的,它不断地用于监听event,之后再对监听到的event进行处理。
有趣之处在于,这个event loop是single thread,意味着任何时候程序只能处理一个event,处理完这一个再处理下一个,相当于一个queue。
因此,javascript实际上就是在执行一个又一个的event handler,当前这个event handler又可以register另一个event handler(设置对另外某个event的监听)。
举个🌰:
setTimeout(function() {
console.log('In timeout!');
}, 0);
console.log('Not in timeout');
“Not in timeout” 会先与 “In timeout!”输出。
原因是,当前这个event loop中,setTimeout register了一个event handler,它的功能是输出"In timeout"。但是这个event得在下一次iteration of event loop中才能得到执行。而输出"Not in timeout"属于当前iteration of event loop,因此可以输出。