Skip to content

Meteor API

Meteor 全局对象具有许多用于处理实用程序、网络等的函数和属性。

¥Meteor global object has many functions and properties for handling utilities, network and much more.

核心 API

¥Core APIs

Meteor.startup

Summary:

Run code when a client or a server starts.

Arguments:

Source code
NameTypeDescriptionRequired
funcfunction

A function to run on startup.

Yes

在服务器上,该函数将在服务器进程启动完成后立即运行。在客户端上,该函数将在 DOM 准备就绪后立即运行。封装在 Meteor.startup 中的代码始终在所有应用文件加载后运行,因此如果你想从其他文件访问共享变量,则应在此处放置代码。

¥On a server, the function will run as soon as the server process is finished starting. On a client, the function will run as soon as the DOM is ready. Code wrapped in Meteor.startup always runs after all app files have loaded, so you should put code here if you want to access shared variables from other files.

startup 回调的调用顺序与调用 Meteor.startup 的顺序相同。

¥The startup callbacks are called in the same order as the calls to Meteor.startup were made.

在客户端上,将首先调用来自包的 startup 回调,然后调用来自 .html 文件的 <body> 模板,然后调用应用代码。

¥On a client, startup callbacks from packages will be called first, followed by <body> templates from your .html files, followed by your application code.

js
import { Meteor } from "meteor/meteor";
import { LinksCollection } from "/imports/api/links";

Meteor.startup(async () => {
  // If the Links collection is empty, add some data.
  if ((await LinksCollection.find().countAsync()) === 0) {
    await LinksCollection.insertAsync({
      title: "Do the Tutorial",
      url: "https://www.meteor.com/tutorials/react/creating-an-app",
    });
  }
});
js
import React from "react";
import { createRoot } from "react-dom/client";
import { Meteor } from "meteor/meteor";
import { App } from "/imports/ui/App";

// Setup react root
Meteor.startup(() => {
  const container = document.getElementById("react-target");
  const root = createRoot(container);
  root.render(<App />);
});

Meteor.promisify

Summary:

Takes a function that has a callback argument as the last one and promissify it. One option would be to use node utils.promisify, but it won't work on the browser.

Arguments:

Source code
NameTypeDescriptionRequired
fnfunction----Yes
contextObject----No
errorFirstBoolean

If the callback follows the errorFirst style, default to true

No
js
import { Meteor } from "meteor/meteor";

/** @returns function */
const result = Meteor.promisify();
  () => {},
context, // this param is optional

false, // this param is optional
);

Meteor.defer

Summary:

Defer execution of a function to run asynchronously in the background (similar to Meteor.setTimeout(func, 0).

Arguments:

Source code
NameTypeDescriptionRequired
funcfunction

The function to run

Yes
js
import { Meteor } from "meteor/meteor";


const result = Meteor.defer();
  () => {}
);

Meteor.absoluteUrl

Summary:

Generate an absolute URL pointing to the application. The server reads from the ROOT_URL environment variable to determine where it is running. This is taken care of automatically for apps deployed to Galaxy, but must be provided when using meteor build.

Arguments:

Source code
NameTypeDescriptionRequired
pathString

A path to append to the root URL. Do not include a leading "/".

No
optionsObjectNo

Options:

NameTypeDescriptionRequired
secureBoolean

Create an HTTPS URL.

No
replaceLocalhostBoolean

Replace localhost with 127.0.0.1. Useful for services that don't recognize localhost as a domain name.

No
rootUrlString

Override the default ROOT_URL from the server environment. For example: "http://foo.example.com"

No
js
import { Meteor } from "meteor/meteor";


const result = Meteor.absoluteUrl();
  "path",  // this param is optional 
options, // this param is optional
);

Meteor.settings

Summary:

Meteor.settings contains deployment-specific configuration options. You can initialize settings by passing the --settings option (which takes the name of a file containing JSON data) to meteor run or meteor deploy. When running your server directly (e.g. from a bundle), you instead specify settings by putting the JSON directly into the METEOR_SETTINGS environment variable. If the settings object contains a key named public, then Meteor.settings.public will be available on the client as well as the server. All other properties of Meteor.settings are only defined on the server. You can rely on Meteor.settings and Meteor.settings.public being defined objects (not undefined) on both client and server even if there are no settings specified. Changes to Meteor.settings.public at runtime will be picked up by new client connections.

Meteor.release

Summary:

Meteor.release is a string containing the name of the release with which the project was built (for example, "1.2.3"). It is undefined if the project was built using a git checkout of Meteor.

Meteor.isClient

Summary:

Boolean variable. True if running in client environment.

js
import { Meteor } from 'meteor/meteor';

/** @type {Boolean} */
if (Meteor.isClient) {
  // do something
}

Meteor.isServer

Summary:

Boolean variable. True if running in server environment.

js
import { Meteor } from 'meteor/meteor';

/** @type {Boolean} */
if (Meteor.isServer) {
  // do something
}

危险

Meteor.isServer 可用于限制代码运行的位置,但它不会阻止代码发送到客户端。你不想提供给客户端的任何敏感代码(例如包含密码或身份验证机制的代码)都应保存在 server 目录中。

¥Meteor.isServer can be used to limit where code runs, but it does not prevent code from being sent to the client. Any sensitive code that you don’t want served to the client, such as code containing passwords or authentication mechanisms, should be kept in the server directory.

Meteor.isCordova

Summary:

Boolean variable. True if running in a Cordova mobile environment.

js
import { Meteor } from 'meteor/meteor';

/** @type {Boolean} */
if (Meteor.isCordova) {
  // do something
}

Meteor.isDevelopment

Summary:

Boolean variable. True if running in development environment.

js
import { Meteor } from 'meteor/meteor';

/** @type {Boolean} */
if (Meteor.isDevelopment) {
  // do something
}

Meteor.isProduction

Summary:

Boolean variable. True if running in production environment.

js
import { Meteor } from 'meteor/meteor';

/** @type {Boolean} */
if (Meteor.isProduction) {
  // do something
}

Meteor.isModern

Summary:

Boolean variable. True if running in a "modern" JS environment, as determined by the modern package.

js
import { Meteor } from 'meteor/meteor';

/** @type {Boolean} */
if (Meteor.isModern) {
  // do something
}

Meteor.isTest

Summary:

Boolean variable. True when running unit tests (false if running tests in full app mode).

js
import { Meteor } from 'meteor/meteor';

/** @type {Boolean} */
if (Meteor.isTest) {
  // do something
}

Meteor.isAppTest

Summary:

Boolean variable. True if running tests against your application i.e meteor test --full-app.

js
import { Meteor } from 'meteor/meteor';

/** @type {Boolean} */
if (Meteor.isAppTest) {
  // do something
}

Meteor.isPackageTest

Summary:

Boolean variable. True if running tests against a Meteor package.

js
import { Meteor } from 'meteor/meteor';

/** @type {Boolean} */
if (Meteor.isPackageTest) {
  // do something
}

Meteor.gitCommitHash

Summary:

Hexadecimal Git commit hash, if the application is using Git for version control. Undefined otherwise.

方法 API

¥Method APIs

Meteor 方法是远程过程调用 (RPC),是由 Meteor.methods 定义并由 Meteor.call 调用的函数。

¥Meteor Methods are Remote Procedure Calls (RPCs) are functions defined by Meteor.methods and called by Meteor.call.

Meteor.methods

Summary:

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

Arguments:

Source code
NameTypeDescriptionRequired
methodsObject

Dictionary whose keys are method names and values are functions.

Yes

定义方法的最基本方法是提供一个函数:

¥The most basic way to define a method is to provide a function:

js
import { Meteor } from "meteor/meteor";

Meteor.methods({
  sum(a, b) {
    return a + b;
  },
});
js
import { Meteor } from "meteor/meteor";

const result = await Meteor.callAsync("sum", 1, 2);
console.log(result); // 3

你可以使用 Meteor.methods 一次定义多个方法。

¥You can use Meteor.methods to define multiple methods at once.

你可以将 Meteor.methods 视为定义远程对象(即服务器 API)的一种方式。

¥You can think of Meteor.methods as a way of defining a remote object that is your server API.

更完整的示例:

¥A more complete example:

js
import { Meteor } from "meteor/meteor";
import { check } from "meteor/check";
import { LinksCollection } from "/imports/api/links";

Meteor.methods({
  async addLink(link) {
    check(link, String); // check if the link is a string

    // Do stuff...
    const linkID = await LinksCollection.insertAsync(link);
    if (/* you want to throw an error */) {
      throw new Meteor.Error('Something is wrong', "Some details");
    }

    return linkID;
  },

  bar() {
    // Do other stuff...
    return 'baz';
  }
});
js
import React from "react";
import { Meteor } from "meteor/meteor";

function Component() {
  const addLink = () =>
    Meteor.callAsync(
      "addLink",
      "https://www.meteor.com/tutorials/react/creating-an-app"
    );

  return (
    <div>
      <button onClick={addLink}>Add Link</button>
    </div>
  );
}

在服务器上调用 methods 可定义可由客户端远程调用的函数。它们应该返回一个 EJSON 值或抛出异常。在你的方法调用中,this 绑定到方法调用对象,它提供以下内容:

¥Calling methods on the server defines functions that can be called remotely by clients. They should return an EJSON-able value or throw an exception. Inside your method invocation, this is bound to a method invocation object, which provides the following:

  • isSimulation:布尔值,如果此调用是存根,则为 true。

    ¥isSimulation: a boolean value, true if this invocation is a stub.

  • unblock:当调用时,允许此客户端的下一个方法开始运行。

    ¥unblock: when called, allows the next method from this client to begin running.

  • userId:当前用户的 ID。

    ¥userId: the id of the current user.

  • setUserId:将当前客户端与用户关联的函数。

    ¥setUserId: a function that associates the current client with a user.

  • connection:在服务器上,connection 接收此方法调用。

    ¥connection: on the server, the connection this method call was received on.

在客户端上调用 methods 可定义与同名服务器方法关联的存根函数。如果你不想,你不必为你的方法定义存根。在这种情况下,方法调用就像其他系统中的远程过程调用一样,你必须等待服务器的结果。

¥Calling methods on the client defines stub functions associated with server methods of the same name. You don't have to define a stub for your method if you don't want to. In that case, method calls are just like remote procedure calls in other systems, and you'll have to wait for the results from the server.

如果你确实定义了存根,当客户端调用服务器方法时,它还将并行运行其存根。在客户端上,存根的返回值将被忽略。运行存根是为了产生副作用:它们旨在模拟服务器方法将执行的操作的结果,但无需等待往返延迟。如果存根抛出异常,它将被记录到控制台。

¥If you do define a stub, when a client invokes a server method it will also run its stub in parallel. On the client, the return value of a stub is ignored. Stubs are run for their side-effects: they are intended to simulate the result of what the server's method will do, but without waiting for the round trip delay. If a stub throws an exception it will be logged to the console.

你始终都在使用方法,因为数据库变量器(insertupdateremove)是作为方法实现的。当你在客户端上调用这些函数中的任何一个时,你都会调用它们的存根版本来更新本地缓存,并向服务器发送相同的写入请求。当服务器响应时,客户端将使用服务器上实际发生的写入更新本地缓存。

¥You use methods all the time, because the database mutators (insert, update, remove) are implemented as methods. When you call any of these functions on the client, you're invoking their stub version that update the local cache, and sending the same write request to the server. When the server responds, the client updates the local cache with the writes that actually occurred on the server.

你不必将所有方法定义放入单个 Meteor.methods 调用中;你可以多次调用它,只要每个方法都有一个唯一的名称。

¥You don't have to put all your method definitions into a single Meteor.methods call; you may call it multiple times, as long as each method has a unique name.

如果客户端调用方法并在收到响应之前断开连接,它将在重新连接时重新调用该方法。这意味着客户端可能会多次调用一个方法,而实际上它只需要调用一次。如果此行为对你的方法有问题,请考虑在客户端上为每个方法调用附加一个唯一 ID,并在服务器上检查是否已经使用此 ID 进行了调用。或者,你可以将 noRetry 选项设置为 true 来使用 Meteor.apply

¥If a client calls a method and is disconnected before it receives a response, it will re-call the method when it reconnects. This means that a client may call a method multiple times when it only means to call it once. If this behavior is problematic for your method, consider attaching a unique ID to each method call on the client, and checking on the server whether a call with this ID has already been made. Alternatively, you can use Meteor.apply with the noRetry option set to true.

在 Meteor 指南中的 方法 文章中阅读有关方法及其使用方法的更多信息。

¥Read more about methods and how to use them in the Methods article in the Meteor Guide.

Meteor.isAsyncCall

Summary:

Tells if the method call came from a call or a callAsync.

此方法可用于确定当前方法调用是否是异步的。如果该方法在服务器上运行并且来自异步调用(Meteor.callAsync),则返回 true

¥This method can be used to determine if the current method invocation is asynchronous. It returns true if the method is running on the server and came from an async call(Meteor.callAsync)

js
import { Meteor } from "meteor/meteor";

Meteor.methods({
  async foo() {
    return Meteor.isAsyncCall();
  },
});
js
import { Meteor } from "meteor/meteor";

const result = await Meteor.callAsync("foo");
console.log(result); // true

Meteor.call("foo", (err, result) => {
  console.log(result); // false
});

this.userId

用户 ID 是一个任意字符串 — 通常是数据库中用户记录的 ID。你可以使用 setUserId 函数设置它。如果你正在使用 Meteor 账户系统,那么这将为你处理。

¥The user id is an arbitrary string — typically the id of the user record in the database. You can set it with the setUserId function. If you're using the Meteor accounts system then this is handled for you.

js
import { Meteor } from "meteor/meteor";

Meteor.methods({
  foo() {
    console.log(this.userId);
  },
});

this.setUserId

调用此函数以更改进行此方法调用的连接上当前登录的用户。这只是设置 userId 的值,以便在此连接上接收未来方法调用。通过 null 注销连接。

¥Call this function to change the currently logged-in user on the connection that made this method call. This simply sets the value of userId for future method calls received on this connection. Pass null to log out the connection.

如果你使用的是 内置 Meteor 账户系统,那么这应该对应于 Meteor.users 集合中文档的 _id 字段。

¥If you are using the built-in Meteor accounts system then this should correspond to the _id field of a document in the Meteor.users collection.

setUserId 不具有追溯力。它会影响当前方法调用和连接上的任何未来方法调用。此连接上的任何先前方法调用仍将看到启动时有效的 userId 值。

¥setUserId is not retroactive. It affects the current method call and any future method calls on the connection. Any previous method calls on this connection will still see the value of userId that was in effect when they started.

如果你还想更改客户端上的登录用户,则在服务器上调用 setUserId 后,在客户端上调用 Meteor.connection.setUserId(userId)

¥If you also want to change the logged-in user on the client, then after calling setUserId on the server, call Meteor.connection.setUserId(userId) on the client.

js
import { Meteor } from "meteor/meteor";

Meteor.methods({
  foo() {
    this.setUserId("some-id");
  },
});

this.connection

在方法调用内部访问。接收此方法的 connection。如果方法与连接无关,则为 null,例如,服务器发起的方法调用。从服务器方法调用的方法(该方法又从客户端发起)共享相同的连接。

¥Access inside a method invocation. The connection that this method was received on. null if the method is not associated with a connection, eg. a server initiated method call. Calls to methods made from a server method which was in turn initiated from the client share the same connection.

Meteor.Error

Summary:

This class represents a symbolic error thrown by a method.

Arguments:

Source code
NameTypeDescriptionRequired
errorString

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 legacy reasons, some built-in Meteor functions such as check throw errors with a number in this field.

Yes
reasonString

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

No
detailsString

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

No
js
import { Meteor } from "meteor/meteor"";

const error = new Meteor.Error();
  "error",
"reason", // this param is optional

"details", // this param is optional
);

例如:

¥For example:

js
import { Meteor } from "meteor/meteor";
// on the server, pick a code unique to this error
// the reason field should be a useful debug message
Meteor.methods({
  methodName() {
    throw new Meteor.Error(
      "logged-out",
      "The user must be logged in to post a comment."
    );
  },
});
js
import { Meteor } from "meteor/meteor";
// on the client
Meteor.call("methodName", function (error) {
  // identify the error
  if (error && error.error === "logged-out") {
    // show a nice error message
    Session.set("errorMessage", "Please log in to post a comment.");
  }
});

如果你想从方法返回错误,请抛出异常。方法可以抛出任何类型的异常。但 Meteor.Error 是服务器发送给客户端的唯一错误类型。如果方法函数抛出不同的异常,那么它将被映射到网络上的已清理版本。具体来说,如果抛出的错误上的 sanitizedError 字段设置为 Meteor.Error,则该错误将发送到客户端。否则,如果没有可用的清理版本,客户端将获得 Meteor.Error(500, 'Internal server error')

¥If you want to return an error from a method, throw an exception. Methods can throw any kind of exception. But Meteor.Error is the only kind of error that a server will send to the client. If a method function throws a different exception, then it will be mapped to a sanitized version on the wire. Specifically, if the sanitizedError field on the thrown error is set to a Meteor.Error, then that error will be sent to the client. Otherwise, if no sanitized version is available, the client gets Meteor.Error(500, 'Internal server error').

Meteor.call

Summary:

Invokes a method with a sync stub, passing any number of arguments.

Arguments:

Source code
NameTypeDescriptionRequired
nameString

Name of method to invoke

Yes
arg1, arg2...EJSONable

Optional method arguments

No
asyncCallbackfunction

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).

No

这是如何使用同步存根调用方法。它将在服务器上运行该方法。如果有存根可用,它还将在客户端上运行存根。(另请参阅 Meteor.apply,它与 Meteor.call 相同,不同之处在于你将参数指定为数组而不是单独的参数,并且可以指定一些控制方法执行方式的选项。)

¥This is how to invoke a method with a sync stub. It will run the method on the server. If a stub is available, it will also run the stub on the client. (See also Meteor.apply, which is identical to Meteor.call except that you specify the parameters as an array instead of as separate arguments and you can specify a few options controlling how the method is executed.)

如果你将回调函数作为最后一个参数(由于函数不可序列化,因此不能作为方法的参数),则该方法将异步运行:它不会返回任何特定内容,也不会引发异常。当方法完成时(在 Meteor.call 返回之前可能发生也可能不会发生),将使用两个参数调用回调:errorresult。如果抛出错误,则 error 将是异常对象。否则,error 将是 undefined,返回值(可能是 undefined)将在 result 中。

¥If you include a callback function as the last argument (which can't be an argument to the method, since functions aren't serializable), the method will run asynchronously: it will return nothing in particular and will not throw an exception. When the method is complete (which may or may not happen before Meteor.call returns), the callback will be called with two arguments: error and result. If an error was thrown, then error will be the exception object. Otherwise, error will be undefined and the return value (possibly undefined) will be in result.

js
// Asynchronous call
Meteor.call('foo', 1, 2, (error, result) => { ... });

如果你未在服务器上传递回调,则方法调用将阻塞,直到该方法完成。它最终将返回方法的返回值,或者如果方法抛出异常,它将抛出异常。(如果异常发生在远程,并且不是 Meteor.Error 异常,则可能映射到 500 服务器错误。)

¥If you do not pass a callback on the server, the method invocation will block until the method is complete. It will eventually return the return value of the method, or it will throw an exception if the method threw an exception. (Possibly mapped to 500 Server Error if the exception happened remotely and it was not a Meteor.Error exception.)

js
// Synchronous call
const result = Meteor.call("foo", 1, 2);

在客户端上,如果你没有传递回调并且不在存根内,call 将返回 undefined,并且你将无法获取该方法的返回值。这是因为客户端没有光纤,因此实际上没有任何方法可以阻止方法的远程执行。

¥On the client, if you do not pass a callback and you are not inside a stub, call will return undefined, and you will have no way to get the return value of the method. That is because the client doesn't have fibers, so there is not actually any way it can block on the remote execution of a method.

最后,如果你在客户端的存根内并调用另一个方法,则不会执行另一个方法(不会生成 RPC,不会发生任何 "real")。如果其他方法具有存根,则该存根将代替该方法并执行。方法调用的返回值是存根函数的返回值。客户端同步执行存根没有问题,这就是为什么客户端可以从方法体内使用同步 Meteor.call 形式的原因,如前所述。

¥Finally, if you are inside a stub on the client and call another method, the other method is not executed (no RPC is generated, nothing "real" happens). If that other method has a stub, that stub stands in for the method and is executed. The method call's return value is the return value of the stub function. The client has no problem executing a stub synchronously, and that is why it's okay for the client to use the synchronous Meteor.call form from inside a method body, as described earlier.

Meteor 跟踪客户端和服务器上方法执行的数据库写入,并且直到所有服务器的写入替换本地缓存中的存根写入时才调用 asyncCallback。在某些情况下,方法的返回值可用和写入可见之间可能会有滞后:例如,如果另一个方法仍未完成写入同一文档,则本地缓存可能不是最新的,直到另一个方法也完成。如果你希望在方法结果从服务器到达后立即处理它,即使方法的写入尚不可用,你也可以指定 onResultReceived 回调到 Meteor.apply

¥Meteor tracks the database writes performed by methods, both on the client and the server, and does not invoke asyncCallback until all of the server's writes replace the stub's writes in the local cache. In some cases, there can be a lag between the method's return value being available and the writes being visible: for example, if another method still outstanding wrote to the same document, the local cache may not be up to date until the other method finishes as well. If you want to process the method's result as soon as it arrives from the server, even if the method's writes are not available yet, you can specify an onResultReceived callback to Meteor.apply.

警告

仅使用 Meteor.call 来调用没有存根或具有同步存根的方法。如果你想使用异步存根调用方法,Meteor.callAsync 可以与任何方法一起使用。

¥Use Meteor.call only to call methods that do not have a stub, or have a sync stub. If you want to call methods with an async stub, Meteor.callAsync can be used with any method.

Meteor.callAsync

Summary:

Invokes a method with an async stub, passing any number of arguments.

Arguments:

Source code
NameTypeDescriptionRequired
nameString

Name of method to invoke

Yes
arg1, arg2...EJSONable

Optional method arguments

No
js
import { Meteor } from "meteor/meteor";

/** @returns Promise */
const result = Meteor.callAsync();
  "name",
{ num: 42 , someProp: "foo" }, // this param is optional
);

Meteor.callAsyncMeteor.call 类似,不同之处在于它会返回一个需要解决才能获得结果的 promise。

¥Meteor.callAsync is just like Meteor.call, except that it'll return a promise that you need to solve to get the result.

Meteor.apply

Summary:

Invoke a method passing an array of arguments.

Arguments:

Source code
NameTypeDescriptionRequired
nameString

Name of method to invoke

Yes
argsArray.<EJSONable>

Method arguments

Yes
optionsObjectNo
asyncCallbackfunction

Optional callback; same semantics as in Meteor.call.

No

Options:

NameTypeDescriptionRequired
waitBoolean

(Client only) If true, don't send this method until all previous method calls have completed, and don't send any subsequent method calls until this one is completed.

No
onResultReceivedfunction

(Client only) This callback is invoked with the error or result of the method (just like asyncCallback) as soon as the error or result is available. The local cache may not yet reflect the writes performed by the method.

No
noRetryBoolean

(Client only) if true, don't send this method again on reload, simply call the callback an error with the error code 'invocation-failed'.

No
throwStubExceptionsBoolean

(Client only) If true, exceptions thrown by method stubs will be thrown instead of logged, and the method will not be invoked on the server.

No
returnStubValueBoolean

(Client only) If true then in cases where we would have otherwise discarded the stub's return value and returned undefined, instead we go ahead and return it. Specifically, this is any time other than when (a) we are already inside a stub or (b) we are in Node and no callback was provided. Currently we require this flag to be explicitly passed to reduce the likelihood that stub return values will be confused with server return values; we may improve this in future.

No
js
import { Meteor } from "meteor/meteor";


const result = Meteor.apply();
  "name",
[{ num: 42 , someProp: "foo" }],
options, // this param is optional

() => {}, // this param is optional
);

Meteor.applyMeteor.call 类似,不同之处在于方法参数作为数组传递而不是直接作为参数传递,并且你可以指定有关客户端如何执行该方法的选项。

¥Meteor.apply is just like Meteor.call, except that the method arguments are passed as an array rather than directly as arguments, and you can specify options about how the client executes the method.

警告

仅使用 Meteor.apply 来调用没有存根或具有同步存根的方法。如果你想使用异步存根调用方法,Meteor.applyAsync 可以与任何方法一起使用。

¥Use Meteor.apply only to call methods that do not have a stub, or have a sync stub. If you want to call methods with an async stub, Meteor.applyAsync can be used with any method.

Meteor.applyAsync

Summary:

Invoke a method passing an array of arguments.

Arguments:

Source code
NameTypeDescriptionRequired
nameString

Name of method to invoke

Yes
argsArray.<EJSONable>

Method arguments

Yes
optionsObjectNo

Options:

NameTypeDescriptionRequired
waitBoolean

(Client only) If true, don't send this method until all previous method calls have completed, and don't send any subsequent method calls until this one is completed.

No
onResultReceivedfunction

(Client only) This callback is invoked with the error or result of the method (just like asyncCallback) as soon as the error or result is available. The local cache may not yet reflect the writes performed by the method.

No
noRetryBoolean

(Client only) if true, don't send this method again on reload, simply call the callback an error with the error code 'invocation-failed'.

No
throwStubExceptionsBoolean

(Client only) If true, exceptions thrown by method stubs will be thrown instead of logged, and the method will not be invoked on the server.

No
returnStubValueBoolean

(Client only) If true then in cases where we would have otherwise discarded the stub's return value and returned undefined, instead we go ahead and return it. Specifically, this is any time other than when (a) we are already inside a stub or (b) we are in Node and no callback was provided. Currently we require this flag to be explicitly passed to reduce the likelihood that stub return values will be confused with server return values; we may improve this in future.

No
returnServerResultPromiseBoolean

(Client only) If true, the promise returned by applyAsync will resolve to the server's return value, rather than the stub's return value. This is useful when you want to ensure that the server's return value is used, even if the stub returns a promise. The same behavior as callAsync.

No
js
import { Meteor } from "meteor/meteor";


const result = Meteor.applyAsync();
  "name",
[{ num: 42 , someProp: "foo" }],
options, // this param is optional
);

Meteor.applyAsyncMeteor.apply 类似,不同之处在于它是一个异步函数,并且它会认为存根是异步的。

¥Meteor.applyAsync is just like Meteor.apply, except it is an async function, and it will consider that the stub is async.

发布和订阅

¥Publish and subscribe

这些函数控制 Meteor 服务器如何发布记录集以及客户端如何订阅这些记录集。

¥These functions control how Meteor servers publish sets of records and how clients can subscribe to those sets.

Meteor.publish

Server only

Summary:

Publish a record set.

To publish records to clients, call `Meteor.publish` on the server with two parameters: the name of the record set, and a _publish function_ that Meteor will call each time a client subscribes to the name.

发布函数可以返回 Collection.Cursor,在这种情况下,Meteor 会将该光标的文档发布到每个订阅的客户端。你还可以返回 Collection.Cursor 数组,在这种情况下,Meteor 将发布所有游标。

¥Publish functions can return a Collection.Cursor, in which case Meteor will publish that cursor's documents to each subscribed client. You can also return an array of Collection.Cursors, in which case Meteor will publish all of the cursors.

警告

如果你在数组中返回多个游标,则它们当前必须全部来自不同的集合。我们希望在未来的版本中解除这一限制。

¥If you return multiple cursors in an array, they currently must all be from different collections. We hope to lift this restriction in a future release.

Arguments:

Source code
NameTypeDescriptionRequired
nameString or Object

If String, name of the record set. If Object, publications Dictionary of publish functions by name. If null, the set has no name, and the record set is automatically sent to all connected clients.

Yes
funcfunction

Function called on the server each time a client subscribes. Inside the function, this is the publish handler object, described below. If the client passed arguments to subscribe, the function is called with the same arguments.

Yes
js
import { Meteor } from "meteor/meteor";
import { check } from "meteor/check";
import { Rooms } from "/imports/api/Rooms";
import { Messages } from "/imports/api/Messages";

// Server: Publish the `Rooms` collection, minus secret info...
Meteor.publish("rooms", function () {
  return Rooms.find(
    {},
    {
      fields: { secretInfo: 0 },
    }
  );
});

// ...and publish secret info for rooms where the logged-in user is an admin. If
// the client subscribes to both publications, the records are merged together
// into the same documents in the `Rooms` collection. Note that currently object
// values are not recursively merged, so the fields that differ must be top
// level fields.
Meteor.publish("adminSecretInfo", function () {
  return Rooms.find(
    { admin: this.userId },
    {
      fields: { secretInfo: 1 },
    }
  );
});

// Publish dependent documents and simulate joins.
Meteor.publish("roomAndMessages", function (roomId) {
  check(roomId, String);

  return [
    Rooms.find(
      { _id: roomId },
      {
        fields: { secretInfo: 0 },
      }
    ),
    Messages.find({ roomId }),
  ];
});

或者,发布函数可以通过调用函数 added(向已发布的记录集添加新文档)、changed(更改或清除已发布记录集中已有文档的某些字段)和 removed(从已发布的记录集中删除文档)来直接控制其已发布的记录集。这些方法由 this 在你的发布函数中提供。

¥Alternatively, a publish function can directly control its published record set by calling the functions added (to add a new document to the published record set), changed (to change or clear some fields on a document already in the published record set), and removed (to remove documents from the published record set). These methods are provided by this in your publish function.

如果发布函数不返回游标或游标数组,则假定它使用底层 added/changed/removed 接口,并且它还必须在初始记录集完成后调用 ready

¥If a publish function does not return a cursor or array of cursors, it is assumed to be using the low-level added/changed/removed interface, and it must also call ready once the initial record set is complete.

js
import { Mongo } from "meteor/mongo";

export const Rooms = new Mongo.Collection("rooms");
export const SecretData = new Mongo.Collection("messages");
js
import { Meteor } from "meteor/meteor";
import { check } from "meteor/check";
import { Rooms, SecretData } from "/imports/api/collections";

// Publish the current size of a collection.
Meteor.publish("countsByRoom", function (roomId) {
  check(roomId, String);

  let count = 0;
  let initializing = true;

  // `observeChanges` only returns after the initial `added` callbacks have run.
  // Until then, we don't want to send a lot of `changed` messages—hence
  // tracking the `initializing` state.
  const handle = Messages.find({ roomId }).observeChanges({
    added: (id) => {
      count += 1;

      if (!initializing) {
        this.changed("counts", roomId, { count });
      }
    },

    removed: (id) => {
      count -= 1;
      this.changed("counts", roomId, { count });
    },

    // We don't care about `changed` events.
  });

  // Instead, we'll send one `added` message right after `observeChanges` has
  // returned, and mark the subscription as ready.
  initializing = false;
  this.added("counts", roomId, { count });
  this.ready();

  // Stop observing the cursor when the client unsubscribes. Stopping a
  // subscription automatically takes care of sending the client any `removed`
  // messages.
  this.onStop(() => handle.stop());
});

// Sometimes publish a query, sometimes publish nothing.
Meteor.publish("secretData", function () {
  if (this.userId === "superuser") {
    return SecretData.find();
  } else {
    // Declare that no data is being published. If you leave this line out,
    // Meteor will never consider the subscription ready because it thinks
    // you're using the `added/changed/removed` interface where you have to
    // explicitly call `this.ready`.
    return [];
  }
});
js
import { Meteor } from "meteor/meteor";
import { Mongo } from "meteor/mongo";
import { Session } from "meteor/session";
// Declare a collection to hold the count object.
const Counts = new Mongo.Collection("counts");

// Subscribe to the count for the current room.
Tracker.autorun(() => {
  Meteor.subscribe("countsByRoom", Session.get("roomId"));
});

// Use the new collection.
const roomCount = Counts.findOne(Session.get("roomId")).count;
console.log(`Current room has ${roomCount} messages.`);

警告

如果你在包含 autopublish 包的项目中调用 Meteor.publish,Meteor 将发出警告消息。你的发布函数仍将起作用。

¥Meteor will emit a warning message if you call Meteor.publish in a project that includes the autopublish package. Your publish function will still work.

在 Meteor 指南中的 数据加载 文章中阅读有关发布物及其使用方法的更多信息。

¥Read more about publications and how to use them in the Data Loading article in the Meteor Guide.

this.userId

Server only

Summary:

Access inside the publish function. The id of the logged-in user, or null if no user is logged in.

这是常量。但是,如果登录用户发生变化,则发布函数将使用新值重新运行,假设它在上次运行时没有抛出错误。

¥This is constant. However, if the logged-in user changes, the publish function is rerun with the new value, assuming it didn't throw an error at the previous run.

this.added

Server only

Summary:

Call inside the publish function. Informs the subscriber that a document has been added to the record set.

Arguments:

Source code
NameTypeDescriptionRequired
collectionString

The name of the collection that contains the new document.

Yes
idString

The new document's ID.

Yes
fieldsObject

The fields in the new document. If _id is present it is ignored.

Yes
js

// this is an instance of Subscription

const result = this.added();
  "collection",
"id",

fields,
);

this.changed

Server only

Summary:

Call inside the publish function. Informs the subscriber that a document in the record set has been modified.

Arguments:

Source code
NameTypeDescriptionRequired
collectionString

The name of the collection that contains the changed document.

Yes
idString

The changed document's ID.

Yes
fieldsObject

The fields in the document that have changed, together with their new values. If a field is not present in fields it was left unchanged; if it is present in fields and has a value of undefined it was removed from the document. If _id is present it is ignored.

Yes
js

// this is an instance of Subscription

const result = this.changed();
  "collection",
"id",

fields,
);

this.removed

Server only

Summary:

Call inside the publish function. Informs the subscriber that a document has been removed from the record set.

Arguments:

Source code
NameTypeDescriptionRequired
collectionString

The name of the collection that the document has been removed from.

Yes
idString

The ID of the document that has been removed.

Yes
js

// this is an instance of Subscription

const result = this.removed();
  "collection",
"id",
);

this.ready

Server only

Summary:

Call inside the publish function. Informs the subscriber that an initial, complete snapshot of the record set has been sent. This will trigger a call on the client to the onReady callback passed to Meteor.subscribe, if any.

js

// this is an instance of Subscription

const result = this.ready();

this.onStop

Server only

Summary:

Call inside the publish function. Registers a callback function to run when the subscription is stopped.

Arguments:

Source code
NameTypeDescriptionRequired
funcfunction

The callback function

Yes
js

// this is an instance of Subscription

const result = this.onStop();
  () => {}
);

如果你在发布处理程序中调用 observeobserveChanges,这是停止观察的地方。

¥If you call observe or observeChanges in your publish handler, this is the place to stop the observes.

this.error

Server only

Summary:

Call inside the publish function. Stops this client's subscription, triggering a call on the client to the onStop callback passed to Meteor.subscribe, if any. If error is not a Meteor.Error, it will be sanitized.

Arguments:

Source code
NameTypeDescriptionRequired
errorError

The error to pass to the client.

Yes
js

// this is an instance of Subscription

const result = this.error();
  Error(error)
);

this.stop

Server only

Summary:

Call inside the publish function. Stops this client's subscription and invokes the client's onStop callback with no error.

js

// this is an instance of Subscription

const result = this.stop();

this.connection

Server only

Summary:

Access inside the publish function. The incoming connection for this subscription.

Meteor.subscribe

Client only

Summary:

Subscribe to a record set. Returns a handle that provides stop() and ready() methods.

Arguments:

Source code
NameTypeDescriptionRequired
nameString

Name of the subscription. Matches the name of the server's publish() call.

Yes
arg1, arg2...EJSONable

Optional arguments passed to publisher function on server.

No
callbacksfunction or Object

Optional. May include onStop and onReady callbacks. If there is an error, it is passed as an argument to onStop. If a function is passed instead of an object, it is interpreted as an onReady callback.

No

当你订阅记录集时,它会告诉服务器将记录发送到客户端。客户端将这些记录存储在本地 Minimongo 集合 中,其名称与发布处理程序的 addedchangedremoved 回调中使用的 collection 参数相同。Meteor 将对传入的记录进行排队,直到你在客户端上使用匹配的集合名称声明 Mongo.Collection

¥When you subscribe to a record set, it tells the server to send records to the client. The client stores these records in local Minimongo collections, with the same name as the collection argument used in the publish handler's added, changed, and removed callbacks. Meteor will queue incoming records until you declare the Mongo.Collection on the client with the matching collection name.

js
// It's okay to subscribe (and possibly receive data) before declaring the
// client collection that will hold it. Assume 'allPlayers' publishes data from
// the server's 'players' collection.
Meteor.subscribe("allPlayers");

// The client queues incoming 'players' records until the collection is created:
const Players = new Mongo.Collection("players");

如果文档当前位于其任何订阅的已发布记录集中,则客户端将看到该文档。如果多个发布物为同一个集合发布具有相同 _id 的文档,则文档将合并到客户端。如果任何顶层字段的值发生冲突,则结果值将是已发布的值之一,任意选择。

¥The client will see a document if the document is currently in the published record set of any of its subscriptions. If multiple publications publish a document with the same _id for the same collection the documents are merged for the client. If the values of any of the top level fields conflict, the resulting value will be one of the published values, chosen arbitrarily.

警告

目前,当多个订阅发布同一篇文档时,合并期间只会比较顶层字段。这意味着,如果文档包含同一顶层字段的不同子字段,则并非所有子字段都会在客户端上可用。我们希望在未来的版本中解除这一限制。

¥Currently, when multiple subscriptions publish the same document only the top level fields are compared during the merge. This means that if the documents include different sub-fields of the same top level field, not all of them will be available on the client. We hope to lift this restriction in a future release.

当服务器 将订阅标记为已准备好 时,不带参数调用 onReady 回调。如果订阅失败或被服务器终止,则使用 Meteor.Error 调用 onStop 回调。如果通过在订阅句柄上或发布内部调用 stop 来停止订阅,则将调用 onStop 而不带参数。

¥The onReady callback is called with no arguments when the server marks the subscription as ready. The onStop callback is called with a Meteor.Error if the subscription fails or is terminated by the server. If the subscription is stopped by calling stop on the subscription handle or inside the publication, onStop is called with no arguments.

Meteor.subscribe 返回订阅句柄,该句柄是一个具有以下属性的对象:

¥Meteor.subscribe returns a subscription handle, which is an object with the following properties:

ts
import { Meteor } from "meteor/meteor";
const handle = Meteor.subscribe("allPlayers");

handle.ready(); // True when the server has marked the subscription as ready

handle.stop(); // Stop this subscription and unsubscribe from the server

handle.subscriptionId; // The id of the subscription this handle is for.

当你在 Tracker.autorun 内运行 Meteor.subscribe 时,你获得的句柄将始终具有相同的 subscriptionId 字段。如果你将订阅句柄存储在某个数据结构中,则可以使用它来对订阅句柄进行数据去重。

¥When you run Meteor.subscribe inside of Tracker.autorun, the handles you get will always have the same subscriptionId field. You can use this to deduplicate subscription handles if you are storing them in some data structure.

如果你在反应式计算中调用 Meteor.subscribe,例如使用 Tracker.autorun,则当计算无效或停止时,订阅将自动取消;没有必要在从 autorun 内部进行的订阅上调用 stop。但是,如果你的运行函数的下一次迭代订阅了相同的记录集(相同的名称和参数),Meteor 足够聪明,可以跳过浪费的取消订阅/重新订阅。例如:

¥If you call Meteor.subscribe within a reactive computation, for example using Tracker.autorun, the subscription will automatically be cancelled when the computation is invalidated or stopped; it is not necessary to call stop on subscriptions made from inside autorun. However, if the next iteration of your run function subscribes to the same record set (same name and parameters), Meteor is smart enough to skip a wasteful unsubscribe/resubscribe. For example:

js
Tracker.autorun(() => {
  Meteor.subscribe("chat", { room: Session.get("currentRoom") });
  Meteor.subscribe("privateMessages");
});

这会让你订阅当前房间中的聊天消息和你的私有消息。当你通过调用 Session.set('currentRoom', 'newRoom') 更改房间时,Meteor 将订阅新房间的聊天消息,取消订阅原始房间的聊天消息,并继续订阅你的私有消息。

¥This subscribes you to the chat messages in the current room and to your private messages. When you change rooms by calling Session.set('currentRoom', 'newRoom'), Meteor will subscribe to the new room's chat messages, unsubscribe from the original room's chat messages, and continue to stay subscribed to your private messages.

发布策略

¥Publication strategies

以下功能可从 Meteor 2.4 或 ddp-server@2.5.0 获得

¥The following features are available from Meteor 2.4 or ddp-server@2.5.0

一旦你开始扩展应用,你可能希望对客户端上发布物数据的处理方式有更多控制。有三种发布策略:

¥Once you start scaling your application you might want to have more control on how the data from publications is being handled on the client. There are three publications strategies:

SERVER_MERGE

SERVER_MERGE 是默认策略。使用此策略时,服务器会维护连接订阅的所有数据的副本。这允许我们仅通过多个发布发送增量。

¥SERVER_MERGE is the default strategy. When using this strategy, the server maintains a copy of all data a connection is subscribed to. This allows us to only send deltas over multiple publications.

NO_MERGE_NO_HISTORY

NO_MERGE_NO_HISTORY 策略导致服务器将所有发布数据直接发送到客户端。它不记得它之前发送给客户端的内容,并且在订阅停止时不会触发已删除的消息。仅应在特殊用例(如发送并忘记队列)的情况下选择此选项。

¥The NO_MERGE_NO_HISTORY strategy results in the server sending all publication data directly to the client. It does not remember what it has previously sent to client and will not trigger removed messages when a subscription is stopped. This should only be chosen for special use cases like send-and-forget queues.

NO_MERGE

NO_MERGENO_MERGE_NO_HISTORY 类似,但服务器会记住它发送给客户端的 ID,以便在订阅停止时将其删除。当集合仅在单个发布中使用时,可以使用此策略。

¥NO_MERGE is similar to NO_MERGE_NO_HISTORY but the server will remember the IDs it has sent to the client so it can remove them when a subscription is stopped. This strategy can be used when a collection is only used in a single publication.

当选择 NO_MERGE 时,客户端将优雅地处理重复事件而不会引发异常。具体来说:

¥When NO_MERGE is selected the client will be handling gracefully duplicate events without throwing an exception. Specifically:

  • 当我们收到客户端集合中已存在的文档的已添加消息时,它将被更改。

    ¥When we receive an added message for a document that is already present in the client's collection, it will be changed.

  • 当我们收到客户端集合中没有的文档的更改消息时,它将被添加。

    ¥When we receive a change message for a document that is not in the client's collection, it will be added.

  • 当我们收到客户端集合中不存在的文档的已删除消息时,什么也不会发生。

    ¥When we receive a removed message for a document that is not in the client's collection, nothing will happen.

你可以从 DDPServer 导入发布策略。

¥You can import the publication strategies from DDPServer.

js
import { DDPServer } from "meteor/ddp-server";

const { SERVER_MERGE, NO_MERGE_NO_HISTORY, NO_MERGE } =
  DDPServer.publicationStrategies;

你可以使用以下方法设置或获取发布的发布策略:

¥You can use the following methods to set or get the publication strategy for publications:

setPublicationStrategy

Server only

Summary:

Set publication strategy for the given collection. Publications strategies are available from DDPServer.publicationStrategies. You call this method from Meteor.server, like Meteor.server.setPublicationStrategy()

Arguments:

Source code
NameTypeDescriptionRequired
collectionNameString----Yes
strategyObject----Yes

对于 foo 集合,你可以设置 NO_MERGE 策略,如下所示:

¥For the foo collection, you can set the NO_MERGE strategy as shown:

js
import { DDPServer } from "meteor/ddp-server";
Meteor.server.setPublicationStrategy(
  "foo",
  DDPServer.publicationStrategies.NO_MERGE
);

getPublicationStrategy

Server only

Summary:

Gets the publication strategy for the requested collection. You call this method from Meteor.server, like Meteor.server.getPublicationStrategy()

Arguments:

Source code
NameTypeDescriptionRequired
collectionNameString----Yes
js
import { Meteor } from "meteor/meteor";

/** @returns Object */
const result = Meteor.server.getPublicationStrategy();
  "collectionName"
);

服务器连接

¥Server connections

用于管理和检查 Meteor 客户端和服务器之间网络连接的函数。

¥Functions to manage and inspect the network connection between the Meteor client and server.

Meteor.status

Client only

Summary:

Get the current connection status. A reactive data source.

js
import { Meteor } from "meteor/meteor";
const status = Meteor.status();

console.log(status);
//          ^^^^
// {
//   connected: Boolean,
//   status: String,
//   retryCount: Number,
//   retryTime: Number,
//   reason: String,
// }

Status 对象具有以下字段:

¥Status object has the following fields:

  • connected - 布尔值:如果当前连接到服务器,则为 True。如果为 false,则更改和方法调用将排队,直到重新建立连接。

    ¥connected - Boolean : True if currently connected to the server. If false, changes and method invocations will be queued up until the connection is reestablished.

  • status - 字符串:描述当前的重新连接状态。可能的值是 connected(连接已启动并正在运行)、connecting(已断开连接并尝试打开新连接)、failed(永久连接失败;例如,客户端和服务器支持不同版本的 DDP)、waiting(连接失败并等待尝试重新连接)和 offline(用户已断开连接)。

    ¥status - String: Describes the current reconnection status. The possible values are connected (the connection is up and running), connecting (disconnected and trying to open a new connection), failed (permanently failed to connect; e.g., the client and server support different versions of DDP), waiting (failed to connect and waiting to try to reconnect) and offline (user has disconnected the connection).

  • retryCount - 数字:自连接丢失以来客户端尝试重新连接的次数。连接时为 0。

    ¥retryCount - Number: The number of times the client has tried to reconnect since the connection was lost. 0 when connected.

  • retryTime - 数字或未定义:下次重新连接尝试的预计时间。要将其变成下次重新连接的间隔,仅当 statuswaiting 时才会设置此键。你可以使用这个片段:

    ¥retryTime - Number or undefined: The estimated time of the next reconnection attempt. To turn this into an interval until the next reconnection, This key will be set only when status is waiting. You canuse this snippet:

    js
    retryTime - new Date().getTime();
  • reason - 字符串或未定义:如果 statusfailed,则描述连接失败的原因。

    ¥reason - String or undefined: If status is failed, a description of why the connection failed.

Meteor.reconnect

Client only

Summary:

Force an immediate reconnection attempt if the client is not connected to the server.

This method does nothing if the client is already connected.

js
import { Meteor } from "meteor/meteor";


const result = Meteor.reconnect();

Meteor.disconnect

Client only

Summary:

Disconnect the client from the server.

js
import { Meteor } from "meteor/meteor";


const result = Meteor.disconnect();

调用此方法可断开与服务器的连接并停止所有实时数据更新。当客户端断开连接时,它将不会收到集合的更新,方法调用将排队,直到重新建立连接,并且热代码推送将被禁用。

¥Call this method to disconnect from the server and stop all live data updates. While the client is disconnected it will not receive updates to collections, method calls will be queued until the connection is reestablished, and hot code push will be disabled.

调用 Meteor.reconnect 以重新建立连接并恢复数据传输。

¥Call Meteor.reconnect to reestablish the connection and resume data transfer.

当不需要实时更新时,这可用于节省移动设备的电池电量。

¥This can be used to save battery on mobile devices when real time updates are not required.

Meteor.onConnection

Server only

Summary:

Register a callback to be called when a new DDP connection is made to the server.

Arguments:

Source code
NameTypeDescriptionRequired
callbackfunction

The function to call when a new DDP connection is established.

Yes
js
import { Meteor } from "meteor/meteor";

const handle = Meteor.onConnection((connection) => {
  console.log(connection);
  //          ^^^^^^^^^^^
  // {
  //   id: String,
  //   close: Function,
  //   onClose: Function,
  //   clientAddress: String,
  //   httpHeaders: Object,
  // }
});

handle.stop(); // Unregister the callback

onConnection 返回一个具有单一方法 stop 的对象。调用 stop 可取消注册回调,因此在新的连接上将不再调用此回调。

¥onConnection returns an object with a single method stop. Calling stop unregisters the callback, so that this callback will no longer be called on new connections.

回调使用单个参数调用,即服务器端 connection 代表来自客户端的连接。此对象包含以下字段:

¥The callback is called with a single argument, the server-side connection representing the connection from the client. This object contains the following fields:

  • id - 字符串:此连接的全局唯一 ID。

    ¥id - String: A globally unique id for this connection.

  • close - 功能:关闭此 DDP 连接。客户端可以自由重新连接,但如果这样做,将收到具有新 id 的不同连接。

    ¥close - Function: Close this DDP connection. The client is free to reconnect, but will receive a different connection with a new id if it does.

  • onClose - 功能:注册一个在连接关闭时调用的回调。如果连接已关闭,将立即调用回调。

    ¥onClose - Function: Register a callback to be called when the connection is closed. If the connection is already closed, the callback will be called immediately.

  • clientAddress - 字符串:客户端的 IP 地址以点形式表示(例如 127.0.0.1)。如果你在代理后面运行 Meteor 服务器(以便客户端连接到代理而不是直接连接到你的服务器),你需要设置 HTTP_FORWARDED_COUNT 环境变量以便 clientAddress 报告正确的 IP 地址。

    ¥clientAddress - String: The IP address of the client in dotted form (such as 127.0.0.1). If you're running your Meteor server behind a proxy (so that clients are connecting to the proxy instead of to your server directly), you'll need to set the HTTP_FORWARDED_COUNT environment variable for the correct IP address to be reported by clientAddress.

    HTTP_FORWARDED_COUNT 设置为一个整数,表示服务器前面的代理数量。例如,当你的服务器位于一个代理后面时,你会将其设置为 1

    ¥Set HTTP_FORWARDED_COUNT to an integer representing the number of proxies in front of your server. For example, you'd set it to 1 when your server was behind one proxy.

  • httpHeaders - 对象:当连接通过 HTTP 传输(例如使用 Meteor 的默认 SockJS 实现)进入时,此字段包含白名单 HTTP 标头。

    ¥httpHeaders - Object: When the connection came in over an HTTP transport (such as with Meteor's default SockJS implementation), this field contains whitelisted HTTP headers.

    Cookie 被故意排除在标头之外,因为它们对这种传输存在安全风险。有关详细信息和替代方案,请参阅 SockJS 文档

    ¥Cookies are deliberately excluded from the headers as they are a security risk for this transport. For details and alternatives, see the SockJS documentation.

目前,当客户端重新连接到服务器时(例如在暂时失去互联网连接后),它每次都会获得一个新连接。onConnection 回调将再次被调用,新的连接将有一个新的连接 id

¥Currently when a client reconnects to the server (such as after temporarily losing its Internet connection), it will get a new connection each time. The onConnection callbacks will be called again, and the new connection will have a new connection id.

将来,当客户端重新连接完全实现时,从客户端重新连接将重新连接到服务器上的相同连接:不会再次为该连接调用 onConnection 回调,并且该连接仍将具有相同的连接 id

¥In the future, when client reconnection is fully implemented, reconnecting from the client will reconnect to the same connection on the server: the onConnection callback won't be called for that connection again, and the connection will still have the same connection id.

DDP.connect

Summary:

Connect to the server of a different Meteor application to subscribe to its document sets and invoke its remote methods.

Arguments:

Source code
NameTypeDescriptionRequired
urlString

The URL of another Meteor application.

Yes
optionsObjectNo

Options:

NameTypeDescriptionRequired
reloadWithOutstandingBoolean

is it OK to reload if there are outstanding methods?

No
headersObject

extra headers to send on the websockets connection, for server-to-server DDP only

No
_sockjsOptionsObject

Specifies options to pass through to the sockjs client

No
onDDPNegotiationVersionFailurefunction

callback when version negotiation fails.

No
js
import { DDP } from "meteor/ddp-client";
import { Mongo } from "meteor/mongo";
import { Meteor } from "meteor/meteor";
const options = {...};

const otherServer = DDP.connect("http://example.com", options);

otherServer.call("foo.from.other.server", 1, 2, function (err, result) {
  // ...
});

Metepr.call("foo.from.this.server", 1, 2, function (err, result) {
  // ...
});
const remoteColl = new Mongo.Collection("collectionName", { connection: otherServer });
remoteColl.find(...);

要调用另一个 Meteor 应用上的方法或订阅其数据集,请使用应用的 URL 调用 DDP.connectDDP.connect 返回一个提供以下内容的对象:

¥To call methods on another Meteor application or subscribe to its data sets, call DDP.connect with the URL of the application. DDP.connect returns an object which provides:

默认情况下,客户端会打开与加载它们的服务器的连接。调用 Meteor.subscribeMeteor.statusMeteor.callMeteor.apply 时,你正在使用返回该默认服务器的连接。

¥By default, clients open a connection to the server from which they're loaded. When you call Meteor.subscribe, Meteor.status, Meteor.call, and Meteor.apply, you are using a connection back to that default server.

DDP.onReconnect

Summary:

Register a function to call as the first step of reconnecting. This function can call methods which will be executed before any other outstanding methods. For example, this can be used to re-establish the appropriate authentication context on the connection.

Arguments:

Source code
NameTypeDescriptionRequired
callbackfunction

The function to call. It will be called with a single argument, the connection object that is reconnecting.

Yes
js
import { DDP } from "meteor/ddp-client";


const result = DDP.onReconnect();
  () => {}
);

计时器

¥Timers

Meteor 使用全局环境变量来跟踪当前请求的用户等内容。要确保这些变量具有正确的值,你需要使用 Meteor.setTimeout 而不是 setTimeout,使用 Meteor.setInterval 而不是 setInterval

¥Meteor uses global environment variables to keep track of things like the current request's user. To make sure these variables have the right values, you need to use Meteor.setTimeout instead of setTimeout and Meteor.setInterval instead of setInterval.

这些函数的工作方式与它们的原生 JavaScript 等效函数相同。如果你调用原生函数,你将收到一个错误,指出 Meteor 代码必须始终在 Fiber 中运行,并建议使用 Meteor.bindEnvironment

¥These functions work just like their native JavaScript equivalents. If you call the native function, you'll get an error stating that Meteor code must always run within a Fiber, and advising to use Meteor.bindEnvironment.

Meteor.setTimeout

Summary:

Call a function in the future after waiting for a specified delay.

Arguments:

Source code
NameTypeDescriptionRequired
funcfunction

The function to run

Yes
delayNumber

Number of milliseconds to wait before calling function

Yes
js
import { Meteor } from "meteor/meteor";


const result = Meteor.setTimeout();
  () => {},
42,
);

返回 Meteor.clearTimeout 可以使用的句柄。

¥Returns a handle that can be used by Meteor.clearTimeout.

Meteor.setInterval

Summary:

Call a function repeatedly, with a time delay between calls.

Arguments:

Source code
NameTypeDescriptionRequired
funcfunction

The function to run

Yes
delayNumber

Number of milliseconds to wait between each function call.

Yes
js
import { Meteor } from "meteor/meteor";


const result = Meteor.setInterval();
  () => {},
42,
);

返回 Meteor.clearInterval 可以使用的句柄。

¥Returns a handle that can be used by Meteor.clearInterval.

Meteor.clearTimeout

Summary:

Cancel a function call scheduled by Meteor.setTimeout.

Arguments:

Source code
NameTypeDescriptionRequired
idObject

The handle returned by Meteor.setTimeout

Yes
js
import { Meteor } from "meteor/meteor";


const result = Meteor.clearTimeout();
  id
);

Meteor.clearInterval

Summary:

Cancel a repeating function call scheduled by Meteor.setInterval.

Arguments:

Source code
NameTypeDescriptionRequired
idObject

The handle returned by Meteor.setInterval

Yes
js
import { Meteor } from "meteor/meteor";


const result = Meteor.clearInterval();
  id
);

环境变量

¥Enviroment variables

Meteor 使用 AsyncLocalStorage 实现 Meteor.EnvironmentVariable,允许跨异步边界维护上下文。Meteor.EnvironmentVariableMeteor.bindEnvironment、promise 和许多其他 Meteor API 配合使用,以在异步代码中保留上下文。它在 Meteor 中的一些使用示例是将当前用户存储在方法中,并记录使用 audit-argument-checks 时已检查哪些参数。

¥Meteor implements Meteor.EnvironmentVariable with AsyncLocalStorage, which allows for maintaining context across asynchronous boundaries. Meteor.EnvironmentVariable works with Meteor.bindEnvironment, promises, and many other Meteor API's to preserve the context in async code. Some examples of how it is used in Meteor are to store the current user in methods, and record which arguments have been checked when using audit-argument-checks.

js
import { Meteor } from "meteor/meteor";
const currentRequest = new Meteor.EnvironmentVariable();

function log(message) {
  const requestId = currentRequest.get() || "None";
  console.log(`[${requestId}]`, message);
}

currentRequest.withValue("12345", () => {
  log("Handling request"); // Logs: [12345] Handling request
});

Meteor.EnvironmentVariable

Summary:

Constructor for EnvironmentVariable

js
import { Meteor } from "meteor/meteor"";

const environmentVariable = new Meteor.EnvironmentVariable();

);

Meteor.EnvironmentVariableAsync

Summary:

Constructor for EnvironmentVariable

js
import { Meteor } from "meteor/meteor"";

const environmentVariableAsync = new Meteor.EnvironmentVariableAsync();

);

Meteor.EnvironmentVariable.get

Summary:

Getter for the current value of the variable, or undefined if called from outside a withValue callback.

js
import { Meteor } from "meteor/meteor";

/** @returns any */
const result = Meteor.EnvironmentVariable.get();

Meteor.EnvironmentVariable.withValue

Summary:

takes a value and a function, calls the function with the value set for the duration of the call

Arguments:

Source code
NameTypeDescriptionRequired
valueany

The value to set for the duration of the function call

Yes
funcfunction

The function to call with the new value of the

Yes
optionsObject

Optional additional properties for adding in asl

No
js
import { Meteor } from "meteor/meteor";

/** @returns Promise<any> */
const result = Meteor.EnvironmentVariable.withValue();
  any,
() => {},

options, // this param is optional
);

Meteor.bindEnvironment

Summary:

Stores the current Meteor environment variables, and wraps the function to run with the environment variables restored. On the server, the function is wrapped within Async Local Storage.

This function has two reasons:

  1. Return the function to be executed on the MeteorJS context, having it assigned in Async Local Storage.
  2. Better error handling, the error message will be more clear.

Arguments:

Source code
NameTypeDescriptionRequired
funcfunction

Function that is wrapped

Yes
onExceptionfunction----Yes
_thisObject

Optional this object against which the original function will be invoked

Yes
js
import { Meteor } from "meteor/meteor";

/** @returns function */
const result = Meteor.bindEnvironment();
  () => {},
() => {},

_this,
);