Wed, 31 Dec 2014 13:27:57 +0100
Ignore runtime configuration files generated during quality assurance.
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 "use strict";
7 /**
8 * Helpers for async functions. Async functions are generator functions that are
9 * run by Tasks. An async function returns a Promise for the resolution of the
10 * function. When the function returns, the promise is resolved with the
11 * returned value. If it throws the promise rejects with the thrown error.
12 *
13 * See Task documentation at https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/Task.jsm.
14 */
16 let {Cu} = require("chrome");
17 let {Task} = require("resource://gre/modules/Task.jsm");
18 let {Promise} = require("resource://gre/modules/Promise.jsm");
20 /**
21 * Create an async function from a generator function.
22 *
23 * @param Function func
24 * The generator function that to wrap as an async function.
25 * @return Function
26 * The async function.
27 */
28 exports.async = function async(func) {
29 return function(...args) {
30 return Task.spawn(func.apply(this, args));
31 };
32 };
34 /**
35 * Create an async function that only executes once per instance of an object.
36 * Once called on a given object, the same promise will be returned for any
37 * future calls for that object.
38 *
39 * @param Function func
40 * The generator function that to wrap as an async function.
41 * @return Function
42 * The async function.
43 */
44 exports.asyncOnce = function asyncOnce(func) {
45 const promises = new WeakMap();
46 return function(...args) {
47 let promise = promises.get(this);
48 if (!promise) {
49 promise = Task.spawn(func.apply(this, args));
50 promises.set(this, promise);
51 }
52 return promise;
53 };
54 };
57 /**
58 * Call a function that expects a callback as the last argument and returns a
59 * promise for the result. This simplifies using callback APIs from tasks and
60 * async functions.
61 *
62 * @param Any obj
63 * The |this| value to call the function on.
64 * @param Function func
65 * The callback-expecting function to call.
66 * @param Array args
67 * Additional arguments to pass to the method.
68 * @return Promise
69 * The promise for the result. If the callback is called with only one
70 * argument, it is used as the resolution value. If there's multiple
71 * arguments, an array containing the arguments is the resolution value.
72 * If the method throws, the promise is rejected with the thrown value.
73 */
74 function promisify(obj, func, args) {
75 return new Promise(resolve => {
76 args.push((...results) => {
77 resolve(results.length > 1 ? results : results[0]);
78 });
79 func.apply(obj, args);
80 });
81 }
83 /**
84 * Call a method that expects a callback as the last argument and returns a
85 * promise for the result.
86 *
87 * @see promisify
88 */
89 exports.promiseInvoke = function promiseInvoke(obj, func, ...args) {
90 return promisify(obj, func, args);
91 };
93 /**
94 * Call a function that expects a callback as the last argument.
95 *
96 * @see promisify
97 */
98 exports.promiseCall = function promiseCall(func, ...args) {
99 return promisify(undefined, func, args);
100 };