Task.jsm 编辑

Obsolete
This feature is obsolete. Although it may still work in some browsers, its use is discouraged since it could be removed at any time. Try to avoid using it.

The Task.jsm JavaScript code module implements a subset of Task.js to make sequential, asynchronous operations simple, using the power of JavaScript's yield operator. To use it, you first need to import the code module into your JavaScript scope:

Components.utils.import("resource://gre/modules/Task.jsm");

Introduction

For an introduction to tasks, you may start from the Task.js documentation, keeping in mind that only the core subset is implemented in this module.

Tasks are built upon generator functions and promises. The Task.spawn() function takes a generator function and starts running it as a task. Every time the task yields a promise, it waits until the promise is resolved. Task.spawn() returns a promise that is resolved when the task completes successfully, or is rejected if an exception occurs.

You can use the yield operator inside the generator function to wait on a promise, spawn another task, or propagate a value:

let resolutionValue = yield (promise/generator/iterator/value);
  • If you specify a promise, the yield operator returns its resolution value as soon as the promise is resolved. If the promise is rejected, its rejection reason is thrown as an exception.
  • If you specify a generator function or the iterator returned by a generator function, then Task.spawn() is implicitly called, and the yield operator works on the returned promise. This reduces the syntax overhead of calling Task.spawn() explicitly when you want to recurse into other task functions.
  • If you specify a function that is not a generator, it is called with no arguments, and the yield operator returns the return value of the function. This comes in handy when iterating over function lists where some items have been converted to tasks and some not.
  • If you specify anything else, the yield operator returns exactly what you specified.

Method overview

Function async(aTask);
Promise spawn(aTask);

Properties

AttributeTypeDescription
Result Read onlyConstructorConstructs a special exception that, when thrown inside a legacy generator function, allows the associated task to be resolved with a specific value. Example:
Task.spawn( function() { yield ... ; throw new Task.Result("Value"); }
Note: If you want to exit early from a generator function, without returning a value for the task, you can just use the return statement without any arguments.

Note: If you want to return a result from a non-legacy generator function, don't use this. Return the value instead:
Task.spawn( function*() { yield ... ; return "Value"; }

Methods

async()

Create and return an "async function" that starts a new task.

Function async(
  aTask
);

async() is similar to spawn(), except that:

  • it doesn't immediately start the task, rather it returns an "async function" that starts the task when the function is called;

  • it binds the task to the async function's this object and arguments;

  • it requires the task to be a function.

async() simplifies the common pattern of implementing a method via a task, like this simple object with a greet method that has a name parameter and spawns a task to send a greeting and return its reply:

let greeter = {
  message: "Hello, NAME!",
  greet: function(name) {
    return Task.spawn((function* () {
      return yield sendGreeting(this.message.replace(/NAME/, name));
    }).bind(this);
  })
};

With async(), the method can be declared succinctly:

let greeter = {
  message: "Hello, NAME!",
  greet: Task.async(function* (name) {
    return yield sendGreeting(this.message.replace(/NAME/, name));
  })
};

While maintaining identical semantics:

greeter.greet("Mitchell").then((reply) => { ... }); // behaves the same

spawn()

Creates and starts a new task.

Promise spawn(
  aTask
);
Parameters
aTask
This parameter accepts different data types:
  • If you specify a generator function, it is called with no arguments to retrieve the associated iterator. The generator function is a task, that is can yield promise objects to wait upon. The promise returned by the task either fulfills with the returned value if generator returns or rejects with the thrown error if the generator throws.
  • If you specify the iterator returned by a generator function you called, the generator function is also executed as a task. This allows you to call the function with arguments. The promise returned by the task either fulfills with the returned value if generator returns or rejects with the thrown error if the generator throws.
  • If you specify a function that is not a generator, it is called with no arguments, and its return value is used to fulfill the returned promise.
  • If you specify anything else, you get a promise that is already fulfilled with the specified value.
Return value

A promise that is fulfills when the task returns or rejects when the task throws an exception.

Examples

General example

Cu.import("resource://gre/modules/Task.jsm");

Task.spawn(function* () {

  // This is our task.  It is a generator function because it contains the
  // "yield" operator at least once.  Let's create a promise object, wait on
  // it and capture its resolution value.
  let myPromise = getPromiseResolvedOnTimeoutWithValue(1000, "Value");
  let result = yield myPromise;

  // This part is executed only after the promise above is resolved (after
  // one second, in this imaginary example).  We can easily loop while
  // calling asynchronous functions, and wait multiple times.
  for (let i = 0; i < 3; i++) {
    result += yield getPromiseResolvedOnTimeoutWithValue(50, "!");
  }

 return "Resolution result for the task: " + result;

}).then(function (result) {

  // result == "Resolution result for the task: Value!!!"

  // The result is undefined if no special Task.Result exception was thrown.

}, function (exception) {

  // Failure!  We can inspect or report the exception.

});

Exception handling

Components.utils.import("resource://gre/modules/osfile.jsm")
Components.utils.import("resource://gre/modules/Task.jsm")

Task.spawn(function* () {
  let currentDir = yield OS.File.getCurrentDirectory();
  let path = OS.Path.join(currentDir, ".mozconfig");

  try {
    let info = yield OS.File.stat(path);
    console.log("The .mozconfig file is " + info.size + " bytes long.");
  } catch (ex if ex instanceof OS.File.Error && ex.becauseNoSuchFile) {
    console.log("You don't have .mozconfig in " + currentDir);
  }
}).then(null, Components.utils.reportError);

In this example, if the promise returned by OS.File.stat is rejected, an exception is thrown inside the task. If the reason for the exception is that the file doesn't exist, this is treated as an expected condition, and the task will complete succesfully.

Any other unhandled exception that is thrown inside the task is reported by Components.utils.reportError.

See also

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

词条统计

浏览:105 次

字数:12043

最后编辑:7年前

编辑次数:0 次

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文