Meteor.js快速接触

Meteor

基于Node.js的一个框架。特点:实时数据(基于Websocket),客户端和服务端可以共享代码,很重。

本文主要讲几个模块:Collection,Methods,Pub/Sub,DDP
适合人群: 未接触过Meteor或接触不超过一个星期

开始

安装 Meteor

$ curl https://install.meteor.com | sh
创建新的应用
meteor create [APPNAME]
安装包
meteor npm install

Meteor的文件结构

也是限制地比较死,最外层的文件结构
/client 客户端代码
/imports 外部引用代码
/server 服务端代码
/lib 一些全局的可以在这里声明

文件加载顺序

  • 同一层级下,以文件名的字母顺序载入,有时候需要为了这个改文件名。。
  • 先载入/lib下的文件

Core

isClient, isServer来判断时客户端还是服务端,可以分别开来执行
isDevelopment, isProduction来判断开发环境还是线上环境
settings配置文件
这些都是全局的,使用类似
Meteor.settingMeteor.isClient

Collection

一般来说,Collection的声明是共用的,所以不在client也不再server中。
Meteor.js内部集成了MongoDB,好像目前也只支持MongoDB,若要结合其他,可以发起HTTP,DDP,RPC等(后续讲到)
创建一个集合,注意:这里的Mongo是全局变量
Post = new Mongo.Collection('post')
在客户端和服务端中,都有这个概念,虽然定义的语句相同,但是实际的意义却是不同。它们通过(Pub/Sub)来对数据进行同步。
其CURD的操作和MongoDB的语法一致,比如:

1
2
3
4
> db.posts.insert({title: "A new post"});

> db.posts.find();
{ "_id": ObjectId(".."), "title" : "A new post"};

客户端集合
客户端的集合更加有趣。当你在客户端申明 Posts = new Mongo.Collection(‘posts’); 你实际上是创建了一个本地的,在浏览器缓存中的真实的 Mongo 集合。 当我们说客户端集合被”缓存”是指它保存了你数据的一个子集,而且对这些数据提供了十分快速的访问。

有一点我们必须要明白,因为这是 Meteor 工作的一个基础: 通常说来,客户端的集合的数据是你 Mongo 数据库的所有数据的一个子集(毕竟我们不会想把整个数据库的数据全传到客户端来)。

第二,那些数据是被存储在浏览器内存中的,也就是说访问这些数据几乎不需要时间,不像去服务器访问 Posts.find() 那样需要等待,因为数据事实上已经载入了。

在 Meteor 中,find() 返回值是一个游标。游标是一种从动数据源。如果你想输出内容,你可以对游标使用 fetch() 来把游标转换成数组。

发布与订阅

发布与订阅用语客户端与服务端的数据交互,基本上是实时性比较高的数据才使用。
简单的代码如下:

1
2
3
4
5
6
// 在服务器端
Meteor.publish('posts', function() {
return Posts.find({flagged: false});
});
// 在客户端
Meteor.subscribe('posts', 'bob-smith');

如果需要使用多个集合,可以选择使用publish-composite
使用命令 meteor add reywood:publish-composite安装,一个简单的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
Meteor.publishComposite("userCommentsComposite", function(userId) {
return {
find: function() {
// 根据用户 Id 查询出该用户所有的评论集合,注意这里是集合
return Comment.collection.find({userId: userId});
},
children: [
{
find: function(comment) {
// 遍历查询出来的评论集合中所有信息,根据每一条评论关联的文章 Id 查询文章数据
console.log("Get activityId by commantId : commandId =", comment._id, " commandLinkObjectId =", comment.linkedObjectId);
return Activities.find({_id: comment.linkedObjectId});
},
children: [
{
find: function(activity) {
// 查询该文章所有的点赞信息
console.log("Get like info by activityId :", activity._id);
return Like.collection.find({linkedObjectId: activity._id});
}
},
{
find: function(activity) {
// 查询该文章的作者信息
console.log("Get activity user info by activity.userId :", activity.userId);
return Meteor.users.find({_id: activity.userId});
}
}
]
}
]
}
});

其具体实现有点类似,Promise.then(data=>{})的实现,也是数据一层层传递给children

Methods

Meteor不像普通的web框架是通过req/res的方式来操作数据,也就没有最近流行的RESTFUL的风格,客户端请求服务端的数据,可以通过Methods来实现,可以理解为Req/Res。
在服务端和客户端都可以

创建Methods

1
2
3
4
5
6
7
8
Meteor.methods({
say: () => {

}
walk: () => {

}
});

调用Methods

客户端和服务端都可以调用Methods,只是服务端只能调用服务端的,而客户端可以都可以,并优先调用服务端的(即同时存在服务端声明的Methods和客户端声明的Methods时,调用的时候为服务端的)。

1
2
3
4
5
//Method.call 或者 Method.apply ,区别和js类似,就是参数的不同。
Meteor.apply("test",[1,2],function(err,res){
if(err){
}
});

Meteor.methods中函数的上下文对象 this

  1. this.userId
    调用这个函数的用户的id ,类型:string。如果用户没有登录,值为null。 该属性在 Server的Meteor.methods和Client的Meteor.methods都存在。用官方的描述就是Anywhere。 这个属性依赖Meteor的accounts 模块。
  2. this.unblock()
    On the server, methods from a given client run one at a time. The N+1th invocation from a client won’t start until the Nth invocation returns. However, you can change this by calling this.unblock. This will allow the N+1th invocation to start running in a new fiber.

DDP

这个类只有个方法 DDP.connect(url)。DDP可以认为是一个类似RPC的实现,对于不同的开发语言,也有对应的包。

1
2
3
4
5
6
7
8
var remote =  DDP.connect("http://localhost:3010");//链接远程服务器
remote.methods({
say:function(){ console.log("hello world")}
}) //这就是定义远程调用的存根。

remote.call("say","deputy",function(err,res){
console.log(res)
}) //调用远程方法

其他模块

check

check是一个类型验证的库,如
check(userid, String);

accounts

直接使用的账户功能,可以配合Role,简单地实现权限管理。

HTTP

meteor内置了HTTP的包,使用
Http.call(method,url, [options], [asyncCallback])

小结

Meteor.js这个框架很重,虽然提供了很多功能,但是写起来比较不灵活。
适合一个人干完前端和服务端的工作。
熟悉koa或者express的人可能在刚接触的时候比较难以接受,希望此文能有一定的帮助

参考:
Meteor 组合订阅包 publish-composite 使用 http://www.mycode.net.cn/language/javascript/1195.html
Discover Meteor http://wiki.jikexueyuan.com/project/discover-meteor/publish-and-subscribe.html
实时开发框架Meteor API解读系列<一> Meteor.methods http://blog.csdn.net/a6383277/article/details/18098929