Methods

Methods 是可以从客户端调用的服务端函数。当你想做一些比insert, update 或是 remove复杂的事情,或是进行数据验证,而allowdeny又无法满足需求时,使用Methods非常合适。

Methods 可以返回值或是抛出错误。

Meteor.methods(methods)

Anywhere

Defines functions that can be invoked over the network by clients.

Arguments

methods Object

Dictionary whose keys are method names and values are functions.

在服务端调用Meteor.methods定义的函数可以在客户端远程调用。下面是一个method的例子,检查参数,抛出错误:

// On the server
Meteor.methods({
  commentOnPost: function (comment, postId) {
    // Check argument types
    check(comment, String);
    check(postId, String);

    if (! this.userId) {
      throw new Meteor.Error("not-logged-in",
        "Must be logged in to post a comment.");
    }

    // ... do stuff ...

    return "something";
  },

  otherMethod: function () {
    // ... do other stuff ...
  }
});

check函数用于确保method的参数是期望的类型和结构

在method定义中,this绑定到一个method调用对象,method调用对象有几个非常有用的属性,包括:用于标识当前登录用户的this.userId

你不用把所有的method定义都放到一个Meteor.methods里面;可以多次调用Meteor.methods,只要每个method的名字是唯一的。

Latency Compensation

调用服务端的一个method会产生在网络上一个来回的延迟。如果用户由于这个延迟,需要等待一秒才能看到自己的评论显示出来,会让人非常不爽。这就是为什么Meteor有一个叫做 method stubs 的功能。如果你在客户端定义了一个和服务端同名的method,Meteor会运行它,尝试预测服务端运行的结果。当服务端代码执行完毕后,客户端生成的预测结果会被实际结果替代。

insert, update, 和remove的客户端版本,都是以method方式实现,这样在客户端与数据库进行交互的结果就会立即呈现。

Meteor.call(name, [arg1, arg2...], [asyncCallback])

Anywhere

Invokes a method passing any number of arguments.

Arguments

name String

Name of method to invoke

arg1, arg2... EJSON-able Object

Optional method arguments

asyncCallback Function

Optional callback, which is called asynchronously with the error or result after the method is complete. If not provided, the method runs synchronously if possible (see below).

用上面的方法来调用method。

On the client

在客户端调用的Method是异步执行,为了能够获取执行结果,你需要传入一个回调函数。回调函数会收到两个参数errorresult。除非有异常抛出,否则error参数为null。当有异常抛出时,error参数是Meteor.Error的一个实例,同时result参数是undefined。

示例:调用commentOnPostmethod ,传入两个参数commentpostId

// Asynchronous call with a callback on the client
Meteor.call('commentOnPost', comment, postId, function (error, result) {
  if (error) {
    // handle error
  } else {
    // examine result
  }
});

作为方法调用的一部分,Meteor会跟踪数据库的更新,直到所有的更新都发送到客户端之后才调用客户端回调函数。

On the server

在服务端,不用传入回调函数 — 方法调用会阻塞直到执行完毕,返回结果或是抛出异常,就好像直接调用函数一样:

// Synchronous call on the server with no callback
var result = Meteor.call('commentOnPost', comment, postId);

new Meteor.Error(error, [reason], [details])

Anywhere

This class represents a symbolic error thrown by a method.

Arguments

error String

A string code uniquely identifying this kind of error. This string should be used by callers of the method to determine the appropriate action to take, instead of attempting to parse the reason or details fields. For example:

// on the server, pick a code unique to this error
// the reason field should be a useful debug message
throw new Meteor.Error("logged-out", 
  "The user must be logged in to post a comment.");

// on the client
Meteor.call("methodName", function (error) {
  // identify the error
  if (error.error === "logged-out") {
    // show a nice error message
    Session.set("errorMessage", "Please log in to post a comment.");
  }
});

For legacy reasons, some built-in Meteor functions such as check throw errors with a number in this field.

reason String

Optional. A short human-readable summary of the error, like 'Not Found'.

details String

Optional. Additional information about the error, like a textual stack trace.

如果想在method中返回一个错误,使用抛出异常。Method可以抛出任意类型的异常,但是只有Meteor.Error类型的错误会发送到客户端。如果method抛出一个其它类型的异常,客户端会收到Meteor.Error(500, 'Internal server error')