123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108 |
- /* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
- "use strict";
- /**
- * Helpers for async functions. Async functions are generator functions that are
- * run by Tasks. An async function returns a Promise for the resolution of the
- * function. When the function returns, the promise is resolved with the
- * returned value. If it throws the promise rejects with the thrown error.
- *
- * See Task documentation at https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/Task.jsm.
- */
- var {Task} = require("devtools/shared/task");
- var Promise = require("promise");
- /**
- * Create an async function that only executes once per instance of an object.
- * Once called on a given object, the same promise will be returned for any
- * future calls for that object.
- *
- * @param Function func
- * The generator function that to wrap as an async function.
- * @return Function
- * The async function.
- */
- exports.asyncOnce = function asyncOnce(func) {
- const promises = new WeakMap();
- return function (...args) {
- let promise = promises.get(this);
- if (!promise) {
- promise = Task.spawn(func.apply(this, args));
- promises.set(this, promise);
- }
- return promise;
- };
- };
- /**
- * Adds an event listener to the given element, and then removes its event
- * listener once the event is called, returning the event object as a promise.
- * @param nsIDOMElement element
- * The DOM element to listen on
- * @param String event
- * The name of the event type to listen for
- * @param Boolean useCapture
- * Should we initiate the capture phase?
- * @return Promise
- * The promise resolved with the event object when the event first
- * happens
- */
- exports.listenOnce = function listenOnce(element, event, useCapture) {
- return new Promise(function (resolve, reject) {
- let onEvent = function (ev) {
- element.removeEventListener(event, onEvent, useCapture);
- resolve(ev);
- };
- element.addEventListener(event, onEvent, useCapture);
- });
- };
- /**
- * Call a function that expects a callback as the last argument and returns a
- * promise for the result. This simplifies using callback APIs from tasks and
- * async functions.
- *
- * @param Any obj
- * The |this| value to call the function on.
- * @param Function func
- * The callback-expecting function to call.
- * @param Array args
- * Additional arguments to pass to the method.
- * @return Promise
- * The promise for the result. If the callback is called with only one
- * argument, it is used as the resolution value. If there's multiple
- * arguments, an array containing the arguments is the resolution value.
- * If the method throws, the promise is rejected with the thrown value.
- */
- function promisify(obj, func, args) {
- return new Promise(resolve => {
- args.push((...results) => {
- resolve(results.length > 1 ? results : results[0]);
- });
- func.apply(obj, args);
- });
- }
- /**
- * Call a method that expects a callback as the last argument and returns a
- * promise for the result.
- *
- * @see promisify
- */
- exports.promiseInvoke = function promiseInvoke(obj, func, ...args) {
- return promisify(obj, func, args);
- };
- /**
- * Call a function that expects a callback as the last argument.
- *
- * @see promisify
- */
- exports.promiseCall = function promiseCall(func, ...args) {
- return promisify(undefined, func, args);
- };
|