Open rainit2006 opened 7 years ago
lodash javascrip工具库。 lodash(Underscore.js)を使用する目的 配列やオブジェクトの操作をする際に便利 コードの可読性アップ つまりコードをシンプルかつ短縮できる for文、if文を多用せずに済む つまり保守性が高い(変数の状態を知らなくて済む, 関数は参照透過性が保たれている)
常用方法: find, findindex, filter, pluck, map, remove, uniq
var _ =require("lodash");
var result = _.find(Users, {user:"zhangsan"});
Console.log(result);
//变换
_.map(Users, function(user){
return {
name: user.name + xxxxx;
}
});
//链式操作
Console.log(_chain(Users).map(xxxx).filter(xxxx).remove(xxx).value());
eventProxy An implementation of task/event based asynchronous pattern. 解决javascript回调地狱问题。
常见方法:emit(发送消息), all(响应多个消息),after, fail, throw, done all 方法的监听器在满足条件之后 只会执行一次 tail 方法监听器 在满足条件之后,如果组合事件中的某个事件再次被触发,监听器会用最新的数据继续执行。 after()方法来实现事件在执行多次后 执行监听器的单一事件组合订阅方式
var fs=require("fs");
var EventProxy = require("eventProxy");
var ep = new EventProxy();
//fs.readFile("file1.txt", "utf8", function(err, content){
// console.log(content)
//});
/*
/////all function//
ep.all(["read_file1","read_file2","read_file3"], function(content1, content2, content3){
console.log(content1+content2+content3)
});
fs.readFile("file1.txt", "utf8", function(err, content1){
ep.emit("read_file1", content1);
});
fs.readFile("file2.txt", "utf8", function(err, content2){
ep.emit("read_file2", content2);
});
fs.readFile("file3.txt", "utf8", function(err, content3){
ep.emit("read_file3", content3);
});
*/
/*
///////after function
ep.after("read_file", 3, function(contents){
console.log(contents.join())
});
fs.readFile("file1.txt", "utf8", function(err, content1){
ep.emit("read_file", content1);
});
fs.readFile("file2.txt", "utf8", function(err, content2){
ep.emit("read_file", content2);
});
fs.readFile("file3.txt", "utf8", function(err, content3){
ep.emit("read_file", content3);
});
*/
/*
/////fail function
ep.fail(function(err){
console.log("this is a fail function:"+err);
});
//there are no file4.txt file, err must occur.
fs.readFile("file4.txt", "utf8", function(err, content3){
if(err){
ep.throw(err);
//ep.emit("error", err);
}
});
*/
///////after and done function
ep.after("read_file", 1, function(contents){
console.log(contents.join())
});
//fs.readFile("file1.txt", "utf8", ep.done("read_file"));
fs.readFile("file1.txt", "utf8", ep.done("read_file", function(content){
return content+"ooxxx";
}));
ejs-mate 模板引擎
模板方法:layout,partial,block
layout(view)
在模板中的任何位置调用此方法,会将此模板的内容套用在layout的<%- body -%>中。
partial(view, optionsOrCollection)
当在模板中调用这个方法时,会将目标view的内容嵌套到当前的模板中,并表,可以通过optionsOrCollections将相关参数传递给目录view。
block('name')
使用block('name')来创建一个块对象。这个块对象有4个方法,分别是append(),prepend(),replace()和toString()。
<%= 値 %> この記述は、<%= %>内に記述された値を出力します。 変数等を記述すれば、変数に格納された値を出力します。
<%- 値 %> この記述は、<%= %>と同じようなことを実現します。 違いは、HTMLタグを記述した場合に、<%= %>はエスケープ処理を行いますが、このタグはエスケープ処理を行いません。
エスケープ処理とは、
処理系によって特別な意味を割り振られる記号や文字列を、別の記号や文字列に置き換えること。例えば、HTMLで「<」を表示させる場合は「&lt;」と記述する。
数据存储 MongoDB 是一个基于文档的数据库,所有数据是从磁盘上进行读写的。MongoDB善长的是对无模式JSON数据的查询。
而Redis是一个基于内存的键值数据库,它由C语言实现的,与Nginx/ NodeJS工作原理近似,同样以单线程异步的方式工作,先读写内存再异步同步到磁盘,读写速度上比MongoDB有巨大的提升。因此目前很多超高并发的网站/应用都使用Redis做缓存层,普遍认为其性能明显好于MemoryCache。当并发达到一定程度时,即可考虑使用Redis来缓存数据和持久化Session。
将Session存放到Redis中 connect-reids 是一个 Redis 版的 session 存储器,使用node_redis作为驱动。借助它即可在Express中启用Redis来持久化你的Session.
在实际项目中经常将express-session传给connect-redis来启用
var session = require('express-session');
var RedisStore = require('connect-redis')(session);
app.use(session({
store: new RedisStore(options),
secret: 'keyboard cat'
}));
检验
app.use(function (req, res, next) {
if (!req.session) {
return next(new Error('oh no')) // handle error
}
next() // otherwise continue
})
这样你的Session就转移到了Redis数据库,这样做的一个额外好处是,当你的Express服务器突然重启后,用户仍然可以使用当前Cookie中的SessionID从数据库中获取到他的会话状态,做到会话不丢失,在一定程度上提高网站的键壮性。
如果你的NodeJS网站上的所有缓存数据都转移到了Redis后,就可做到完全状态无关,按需扩展网站的规模。
查看redis server里的数据 使用redis-cli。
如果DB的ID指定为0之外,则选择DB: select 1。否则默认指定DB的index是0。
取得DB里保存的key数量: dbsize
获得Key的ID一览: keys *
显示某个key的内容:get “key的ID”
删除Redis里的DB所有内容: flushdb
退出: exit
Mongoose ode.js から MongoDB にアクセススためのライブラリ
Robomongo 管理查询MongoDB内容的工具,可以查看DB和Table内容等。
安装Redis server for Windows 下载地址:https://github.com/MSOpenTech/redis/releases 参考教程:http://keenwon.com/1275.html, https://my.oschina.net/lujianing/blog/204103
启动server时不要直接双击redis-server.exe,要用cmd启动redis-server.exe (会提示找不到config)文件
redis-server.exe redis.windows.conf
安装MongoDB server的business版(for windows) 从MongoDB官网上下载(需要注册个人信息) 安装和配置可以参考: http://qiita.com/boss_ape/items/e4c5024c00de25d3b1b6 要点: 创建log目录和log文件,以后有遇到问题可以看log文件的信息,很有用的。 创建data目录用以存放db数据。 创建config文件指定上述文件路径和ip/port等信息。
顺序: 1,实现router和view Router目录下创建web_router.js文件。在里面,实现对get和post的响应-->即实现页面的跳转。 在app.js里,
var webRouter = require('./routes/web_router');
app.use('/', webRouter);
view里使用ejs模板
2,实现controller
router里将get和post的响应函数交给controller实现。
router.get('/signup', signController.showSignup);
在controller里面去res.render( view画面 ); 或者 调用 数据Module的API。
exports.showSignup = fuction(req, res){ res.render('sign/signup') }
3, 编写数据模型Models 利用session, redis, mongodb来存储session,和数据模型Model。 app.js里
var session = require('express-session');
var RedisStore = require('connect-redis')(session);
...
app.use(session({
secret:'adafdafafdaa',
store: new RedisStore({
port: 6379,
host: '127.0.0.1'
)),
resave: true,
saveUnintialized: true
}));
app.use(function(req, res, next){
app.locals.current_user = req.session.user; //current_user这个变量可以在view页面里被使用
next();
});
创建models目录,在里面创建user.js文件
var mongoose = require('mongoose');
mongoose.connect('mongodb://127.0.0.1/node_club');
var UserSchema = new mongoose.Schema({ username: String, pass: String, email: String});
UserSchema.statics.getUserBySignupInfo = function(username, pass, email, callback){....}
,..
module.exports = mongoose.model('User', UserSchema);
在controller类(sign.js)里:
var UserModel = require('../models/user');
然后直接调用UserModel的函数来实现对user数据的操作。
教程里的错误: html文件里,应该用typeof来判断某变量是否被定义,而不是type typeof(error) == 'undefine'
易犯错误: res和req弄混了。 比如要注意: req.session, req.body
发表话题功能开发 引用js: markdownit.js, markdown-it.js (nodejs用) validator.js: validator.trim(),
路由层: 显示发表话题页面(get处理),提交话题信息(post处理),
评论功能开发 busboy.js: for parsing incoming HTML form data. 实现图片文件上传的处理。
function(req, res){ req.pipe(req.busboy); req.busboy.on('file', function(fieldname, file, filename, encoding, mimetype){ var newfilename = String((new Date()).getTime())+path.extname(filename); var filepath = __dirnam + '/../pulbic/upload/'+newfilename; var url = '/../pulbic/upload/'+newfilename; file.pipe(fs.createWriteString(filepath)); file.on('end', function(){ res.json({ success: true, url: url }); } ); }); }
path模块:
https://www.youtube.com/watch?v=64_p8TXg-lI