1
0
mirror of https://github.com/gryf/pentadactyl-pm.git synced 2026-03-16 23:33:33 +01:00

Promisify some callbackish functions, and remove spaces around = in default arguments, per Python conventions.

This commit is contained in:
Kris Maglione
2014-02-15 20:35:27 -08:00
parent fd20535999
commit bb7486da6c
22 changed files with 250 additions and 115 deletions

View File

@@ -257,8 +257,9 @@ var Bookmarks = Module("bookmarks", {
let engine = hasOwnProperty(this.searchEngines, engineName) && this.searchEngines[engineName]; let engine = hasOwnProperty(this.searchEngines, engineName) && this.searchEngines[engineName];
if (engine && engine.supportsResponseType(responseType)) if (engine && engine.supportsResponseType(responseType))
var queryURI = engine.getSubmission(query, responseType).uri.spec; var queryURI = engine.getSubmission(query, responseType).uri.spec;
if (!queryURI) if (!queryURI)
return (callback || util.identity)([]); return promises.fail();
function parse(req) JSON.parse(req.responseText)[1].filter(isString); function parse(req) JSON.parse(req.responseText)[1].filter(isString);
return this.makeSuggestions(queryURI, parse, callback); return this.makeSuggestions(queryURI, parse, callback);
@@ -271,25 +272,25 @@ var Bookmarks = Module("bookmarks", {
* @param {string} url The URL to fetch. * @param {string} url The URL to fetch.
* @param {function(XMLHttpRequest):[string]} parser The function which * @param {function(XMLHttpRequest):[string]} parser The function which
* parses the response. * parses the response.
* @returns {Promise<Array>}
*/ */
makeSuggestions: function makeSuggestions(url, parser, callback) { makeSuggestions: function makeSuggestions(url, parser) {
function process(req) { let deferred = Promise.defer();
let req = util.fetchUrl(url);
req.then(function process(req) {
let results = []; let results = [];
try { try {
results = parser(req); results = parser(req);
} }
catch (e) { catch (e) {
util.reportError(e); return deferred.reject(e);
}
if (callback)
return callback(results);
return results;
} }
deferred.resolve(results);
}, Cu.reportError);
let req = util.httpGet(url, callback && process); promises.oncancel(deferred, r => promises.cancel(req, reason));
if (callback) return deferred.promise;
return req;
return process(req);
}, },
suggestionProviders: {}, suggestionProviders: {},
@@ -536,7 +537,7 @@ var Bookmarks = Module("bookmarks", {
"Delete a bookmark", "Delete a bookmark",
function (args) { function (args) {
if (args.bang) if (args.bang)
commandline.input(_("bookmark.prompt.deleteAll") + " ", commandline.input(_("bookmark.prompt.deleteAll") + " ").then(
function (resp) { function (resp) {
if (resp && resp.match(/^y(es)?$/i)) { if (resp && resp.match(/^y(es)?$/i)) {
bookmarks.remove(Object.keys(bookmarkcache.bookmarks)); bookmarks.remove(Object.keys(bookmarkcache.bookmarks));
@@ -721,11 +722,12 @@ var Bookmarks = Module("bookmarks", {
ctxt.hasItems = ctxt.completions.length; ctxt.hasItems = ctxt.completions.length;
ctxt.incomplete = true; ctxt.incomplete = true;
ctxt.cache.request = bookmarks.getSuggestions(name, ctxt.filter, function (compl) { ctxt.cache.request = bookmarks.getSuggestions(name, ctxt.filter);
ctxt.cache.request.then(function (compl) {
ctxt.incomplete = false; ctxt.incomplete = false;
ctxt.completions = array.uniq(ctxt.completions.filter(c => compl.indexOf(c) >= 0) ctxt.completions = array.uniq(ctxt.completions.filter(c => compl.indexOf(c) >= 0)
.concat(compl), true); .concat(compl), true);
}); }, Cu.reportError);
}); });
}; };

View File

@@ -1,6 +1,6 @@
// Copyright (c) 2006-2008 by Martin Stubenschrott <stubenschrott@vimperator.org> // Copyright (c) 2006-2008 by Martin Stubenschrott <stubenschrott@vimperator.org>
// Copyright (c) 2007-2011 by Doug Kearns <dougkearns@gmail.com> // Copyright (c) 2007-2011 by Doug Kearns <dougkearns@gmail.com>
// Copyright (c) 2008-2013 Kris Maglione <maglione.k@gmail.com> // Copyright (c) 2008-2014 Kris Maglione <maglione.k@gmail.com>
// //
// This work is licensed for reuse under an MIT license. Details are // This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file. // given in the LICENSE.txt file included with this file.
@@ -845,7 +845,6 @@ var CommandLine = Module("commandline", {
* pop at any time to close the prompt. * pop at any time to close the prompt.
* *
* @param {string} prompt The input prompt to use. * @param {string} prompt The input prompt to use.
* @param {function(string)} callback
* @param {Object} extra * @param {Object} extra
* @... {function} onChange - A function to be called with the current * @... {function} onChange - A function to be called with the current
* input every time it changes. * input every time it changes.
@@ -856,15 +855,16 @@ var CommandLine = Module("commandline", {
* @... {string} default - The initial value that will be returned * @... {string} default - The initial value that will be returned
* if the user presses <CR> straightaway. @default "" * if the user presses <CR> straightaway. @default ""
*/ */
input: function _input(prompt, callback, extra = {}) { input: promises.withCallbacks(function _input([callback, reject], prompt, extra={}, thing={}) {
CommandPromptMode(prompt, update({ onSubmit: callback }, extra)).open(); if (callable(extra))
}, // Deprecated.
[callback, extra] = [extra, thing];
CommandPromptMode(prompt, update({ onSubmit: callback, onCancel: reject }, extra)).open();
}),
readHeredoc: function readHeredoc(end) { readHeredoc: function readHeredoc(end) {
let args; return util.waitFor(commandline.inputMultiline(end));
commandline.inputMultiline(end, function (res) { args = res; });
util.waitFor(() => args !== undefined);
return args;
}, },
/** /**
@@ -873,10 +873,10 @@ var CommandLine = Module("commandline", {
* callback with that string as a parameter. * callback with that string as a parameter.
* *
* @param {string} end * @param {string} end
* @param {function(string)} callback * @returns {Promise<string>}
*/ */
// FIXME: Buggy, especially when pasting. // FIXME: Buggy, especially when pasting.
inputMultiline: function inputMultiline(end, callback) { inputMultiline: promises.withCallbacks(function inputMultiline([callback], end) {
let cmd = this.command; let cmd = this.command;
let self = { let self = {
end: "\n" + end + "\n", end: "\n" + end + "\n",
@@ -902,7 +902,7 @@ var CommandLine = Module("commandline", {
this._autosizeMultilineInputWidget(); this._autosizeMultilineInputWidget();
this.timeout(function () { dactyl.focus(this.widgets.multilineInput); }, 10); this.timeout(function () { dactyl.focus(this.widgets.multilineInput); }, 10);
}, }),
get commandMode() this.commandSession && isinstance(modes.main, modes.COMMAND_LINE), get commandMode() this.commandSession && isinstance(modes.main, modes.COMMAND_LINE),

View File

@@ -895,8 +895,8 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), {
urls = dactyl.parseURLs(urls); urls = dactyl.parseURLs(urls);
if (urls.length > prefs.get("browser.tabs.maxOpenBeforeWarn", 20) && !force) if (urls.length > prefs.get("browser.tabs.maxOpenBeforeWarn", 20) && !force)
return commandline.input(_("dactyl.prompt.openMany", urls.length) + " ", return commandline.input(_("dactyl.prompt.openMany", urls.length) + " ")
function (resp) { .then(function (resp) {
if (resp && resp.match(/^y(es)?$/i)) if (resp && resp.match(/^y(es)?$/i))
dactyl.open(urls, params, true); dactyl.open(urls, params, true);
}); });

View File

@@ -386,8 +386,8 @@ var Editor = Module("editor", XPCOM(Ci.nsIEditActionListener, ModuleBase), {
let keepFocus = modes.stack.some(m => isinstance(m.main, modes.COMMAND_LINE)); let keepFocus = modes.stack.some(m => isinstance(m.main, modes.COMMAND_LINE));
if (!forceEditing && textBox && textBox.type == "password") { if (!forceEditing && textBox && textBox.type == "password") {
commandline.input(_("editor.prompt.editPassword") + " ", commandline.input(_("editor.prompt.editPassword") + " ")
function (resp) { .then(function (resp) {
if (resp && resp.match(/^y(es)?$/i)) if (resp && resp.match(/^y(es)?$/i))
editor.editFieldExternally(true); editor.editFieldExternally(true);
}); });
@@ -424,7 +424,7 @@ var Editor = Module("editor", XPCOM(Ci.nsIEditActionListener, ModuleBase), {
column = 1 + pre.replace(/[^]*\n/, "").length; column = 1 + pre.replace(/[^]*\n/, "").length;
let origGroup = DOM(textBox).highlight.toString(); let origGroup = DOM(textBox).highlight.toString();
let cleanup = util.yieldable(function cleanup(error) { let cleanup = promises.task(function cleanup(error) {
if (timer) if (timer)
timer.cancel(); timer.cancel();
@@ -443,9 +443,11 @@ var Editor = Module("editor", XPCOM(Ci.nsIEditActionListener, ModuleBase), {
DOM(textBox).highlight.remove("EditorEditing"); DOM(textBox).highlight.remove("EditorEditing");
if (!keepFocus) if (!keepFocus)
dactyl.focus(textBox); dactyl.focus(textBox);
for (let group in values(blink.concat(blink, ""))) { for (let group in values(blink.concat(blink, ""))) {
highlight.highlightNode(textBox, origGroup + " " + group); highlight.highlightNode(textBox, origGroup + " " + group);
yield 100;
yield promises.sleep(100);
} }
} }
}); });

View File

@@ -1,6 +1,6 @@
// Copyright (c) 2006-2008 by Martin Stubenschrott <stubenschrott@vimperator.org> // Copyright (c) 2006-2008 by Martin Stubenschrott <stubenschrott@vimperator.org>
// Copyright (c) 2007-2011 by Doug Kearns <dougkearns@gmail.com> // Copyright (c) 2007-2011 by Doug Kearns <dougkearns@gmail.com>
// Copyright (c) 2008-2013 Kris Maglione <maglione.k@gmail.com> // Copyright (c) 2008-2014 Kris Maglione <maglione.k@gmail.com>
// //
// This work is licensed for reuse under an MIT license. Details are // This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file. // given in the LICENSE.txt file included with this file.
@@ -1058,7 +1058,7 @@ var Hints = Module("hints", {
this._extendedhintCount = opts.count; this._extendedhintCount = opts.count;
mappings.pushCommand(); mappings.pushCommand();
commandline.input(["Normal", mode], null, { commandline.input(["Normal", mode], {
autocomplete: false, autocomplete: false,
completer: function (context) { completer: function (context) {
context.compare = () => 0; context.compare = () => 0;

View File

@@ -1,6 +1,6 @@
// Copyright (c) 2006-2008 by Martin Stubenschrott <stubenschrott@vimperator.org> // Copyright (c) 2006-2008 by Martin Stubenschrott <stubenschrott@vimperator.org>
// Copyright (c) 2007-2011 by Doug Kearns <dougkearns@gmail.com> // Copyright (c) 2007-2011 by Doug Kearns <dougkearns@gmail.com>
// Copyright (c) 2008-2013 Kris Maglione <maglione.k@gmail.com> // Copyright (c) 2008-2014 Kris Maglione <maglione.k@gmail.com>
// //
// This work is licensed for reuse under an MIT license. Details are // This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file. // given in the LICENSE.txt file included with this file.

View File

@@ -1,6 +1,6 @@
// Copyright (c) 2006-2008 by Martin Stubenschrott <stubenschrott@vimperator.org> // Copyright (c) 2006-2008 by Martin Stubenschrott <stubenschrott@vimperator.org>
// Copyright (c) 2007-2011 by Doug Kearns <dougkearns@gmail.com> // Copyright (c) 2007-2011 by Doug Kearns <dougkearns@gmail.com>
// Copyright (c) 2008-2013 Kris Maglione <maglione.k@gmail.com> // Copyright (c) 2008-2014 Kris Maglione <maglione.k@gmail.com>
// //
// This work is licensed for reuse under an MIT license. Details are // This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file. // given in the LICENSE.txt file included with this file.

View File

@@ -161,6 +161,7 @@ defineModule("base", {
this.lazyRequire("cache", ["cache"]); this.lazyRequire("cache", ["cache"]);
this.lazyRequire("config", ["config"]); this.lazyRequire("config", ["config"]);
this.lazyRequire("messages", ["_", "Messages"]); this.lazyRequire("messages", ["_", "Messages"]);
this.lazyRequire("promises", ["Task", "promises"]);
this.lazyRequire("services", ["services"]); this.lazyRequire("services", ["services"]);
this.lazyRequire("storage", ["File"]); this.lazyRequire("storage", ["File"]);
this.lazyRequire("util", ["FailedAssertion", "util"]); this.lazyRequire("util", ["FailedAssertion", "util"]);
@@ -915,16 +916,16 @@ Class.Memoize = function Memoize(getter, wait)
} }
}); });
util.yieldable(function () { Task.spawn(function () {
let wait; let wait;
for (var res in getter.call(obj)) { for (var res in getter.call(obj)) {
if (wait !== undefined) if (wait !== undefined)
yield wait; yield promises.sleep(wait);
wait = res; wait = res;
} }
Class.replaceProperty(obj, key, res); Class.replaceProperty(obj, key, res);
done = true; done = true;
})(); });
return this[key]; return this[key];
}; };

View File

@@ -85,10 +85,10 @@ var Buffer = Module("Buffer", {
* @param {string} pref The name of the preference to return. * @param {string} pref The name of the preference to return.
* @returns {Promise<string>} * @returns {Promise<string>}
*/ */
get: promises.withCallback(function get(callback, pref) { get: promises.withCallbacks(function get([resolve], pref) {
services.contentPrefs.getByDomainAndName( services.contentPrefs.getByDomainAndName(
self.uri.host, pref, self.loadContext, self.uri.host, pref, self.loadContext,
callback); resolve);
}), }),
/** /**
@@ -97,10 +97,10 @@ var Buffer = Module("Buffer", {
* @param {string} pref The preference to set. * @param {string} pref The preference to set.
* @param {string} value The value to store. * @param {string} value The value to store.
*/ */
set: promises.withCallback(function set(callback, pref, value) { set: promises.withCallbacks(function set([resolve], pref, value) {
services.contentPrefs.set( services.contentPrefs.set(
self.uri.host, pref, value, self.loadContext, self.uri.host, pref, value, self.loadContext,
callback); resolve);
}), }),
/** /**
@@ -108,9 +108,9 @@ var Buffer = Module("Buffer", {
* *
* @param {string} pref The preference to clear. * @param {string} pref The preference to clear.
*/ */
clear: promises.withCallback(function clear(callback, pref) { clear: promises.withCallbacks(function clear([resolve], pref) {
services.contentPrefs.removeByDomainAndName( services.contentPrefs.removeByDomainAndName(
self.uri.domain, pref, self.loadContext, callback); self.uri.domain, pref, self.loadContext, resolve);
}), }),
})), })),

View File

@@ -132,6 +132,7 @@ var ConfigBase = Class("ConfigBase", {
"options", "options",
"overlay", "overlay",
"prefs", "prefs",
["promises", "Promise", "Task", "promises"],
"protocol", "protocol",
"sanitizer", "sanitizer",
"services", "services",

View File

@@ -15,6 +15,7 @@ defineModule("io", {
lazyRequire("config", ["config"]); lazyRequire("config", ["config"]);
lazyRequire("contexts", ["Contexts", "contexts"]); lazyRequire("contexts", ["Contexts", "contexts"]);
lazyRequire("promises", ["Promise"]);
lazyRequire("storage", ["File", "storage"]); lazyRequire("storage", ["File", "storage"]);
lazyRequire("styles", ["styles"]); lazyRequire("styles", ["styles"]);
lazyRequire("template", ["template"]); lazyRequire("template", ["template"]);
@@ -446,26 +447,29 @@ var IO = Module("io", {
let process = services.Process(file.file); let process = services.Process(file.file);
process.run(false, args.map(String), args.length); process.run(false, args.map(String), args.length);
try {
let deferred = Promise.defer();
if (callable(blocking)) if (callable(blocking))
var timer = services.Timer( // Deprecated.
deferred.promise.then(blocking);
else if (blocking) {
// Deprecated?
while (process.isRunning)
util.threadYield(false, true);
return process.exitValue;
}
let timer = services.Timer(
function () { function () {
if (!process.isRunning) { if (!process.isRunning) {
timer.cancel(); timer.cancel();
util.trapErrors(blocking, self, process.exitValue); deferred.resolve(process.exitValue);
} }
}, },
100, services.Timer.TYPE_REPEATING_SLACK); 100, services.Timer.TYPE_REPEATING_SLACK);
else if (blocking)
while (process.isRunning)
util.threadYield(false, true);
}
catch (e) {
process.kill();
throw e;
}
return process.exitValue; return deferred.promise;
}, },
// TODO: when https://bugzilla.mozilla.org/show_bug.cgi?id=68702 is // TODO: when https://bugzilla.mozilla.org/show_bug.cgi?id=68702 is

View File

@@ -9,10 +9,86 @@ defineModule("promises", {
require: [] require: []
}); });
lazyRequire("services", ["services"]);
lazyRequire("resource://gre/modules/Promise.jsm", ["Promise"]); lazyRequire("resource://gre/modules/Promise.jsm", ["Promise"]);
lazyRequire("resource://gre/modules/Task.jsm", ["Task"]); lazyRequire("resource://gre/modules/Task.jsm", ["Task"]);
function withCallbacks(fn) {
return function wrapper(...args) {
let deferred = Promise.defer();
function resolve(arg) { deferred.resolve(arg); }
function reject(arg) { deferred.reject(arg); }
fn.apply(this, [[resolve, reject, deferred]].concat(args));
return deferred.promise;
}
}
var Promises = Module("Promises", { var Promises = Module("Promises", {
_cancel: WeakMap(),
/**
* Allows promises to be canceled..
*
* @param {Promise} promise The promise to cancel.
* @param {*} arg Argument to be passed to the cancellation
* function.
*/
cancel: function cancel(promise, reason) {
let cleanup = this._cancel.get(promise);
if (cleanup) {
cleanup[0](promise);
cleanup[1].reject(reason);
}
this._cancel.delete(promise);
},
/**
* Registers a cleanup function for the given deferred promise.
*
* @param {Deferred} promise The promise to cancel.
* @param {function} fn The cleanup function.
*/
oncancel: function oncancel(deferred, fn) {
this._cancel.set(deferred.promise, [fn, deferred]);
},
/**
* Returns a promise which resolves after a brief delay.
*/
delay: withCallbacks(function delay([accept]) {
let { mainThread } = services.threading;
mainThread.dispatch(accept, mainThread.DISPATCH_NORMAL);
}),
/**
* Returns a promise which resolves with the given argument.
*/
accept: function fail(arg) {
let deferred = Promise.defer();
deferred.resolve(arg);
return deferred.promise;
},
/**
* Returns a promise which fails with the given argument.
*/
fail: function fail(arg) {
let deferred = Promise.defer();
deferred.reject(arg);
return deferred.promise;
},
/**
* Returns a promise which resolves after the given number of
* milliseconds.
*
* @param {number} delay The number of milliseconds to wait.
*/
sleep: withCallbacks(function sleep([callback], delay) {
this.timeout(callback, delay);
}),
/** /**
* Wraps the given function so that each call spawns a Task. * Wraps the given function so that each call spawns a Task.
* *
@@ -26,21 +102,45 @@ var Promises = Module("Promises", {
}, },
/** /**
* Wraps the given function so that its first argument is a * Returns a promise which resolves when the function *test* returns
* callback which, when called, resolves the returned promise. * true, or *timeout* milliseconds have expired.
*
* @param {function} test The predicate on which to wait.
* @param {Number} timeout The maximum number of milliseconds to
* wait.
* @optional
* @param {number} pollInterval The poll interval, in milliseconds.
* @default 10
*/
waitFor: withCallbacks(function waitFor([accept, reject], test, timeout=null, pollInterval=10) {
let end = timeout && Date.now() + timeout, result;
let timer = services.Timer(
() => {
try {
var result = test();
}
catch (e) {
timer.cancel();
reject(e);
}
if (result) {
timer.cancel();
accept(result);
}
},
pollInterval, services.Timer.TYPE_REPEATING_SLACK);
}),
/**
* Wraps the given function so that its first argument is an array
* of success and failure callbacks which, when called, resolve the
* returned promise.
* *
* @param {function} fn The function to wrap. * @param {function} fn The function to wrap.
* @returns {Promise} * @returns {Promise}
*/ */
withCallback: function withCallback(fn) { withCallbacks: withCallbacks,
return function wrapper(...args) {
let deferred = Promise.defer();
function callback(arg) {
deferred.resolve(arg);
}
return fn.apply(this, [callback].concat(args));
}
},
}); });
endModule(); endModule();

View File

@@ -10,7 +10,7 @@ try {
defineModule("util", { defineModule("util", {
exports: ["DOM", "$", "FailedAssertion", "Math", "NS", "Point", "Util", "XBL", "XHTML", "XUL", "util"], exports: ["DOM", "$", "FailedAssertion", "Math", "NS", "Point", "Util", "XBL", "XHTML", "XUL", "util"],
require: ["dom", "services"] require: ["dom", "promises", "services"]
}); });
lazyRequire("overlay", ["overlay"]); lazyRequire("overlay", ["overlay"]);
@@ -750,10 +750,10 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
* *
* @returns {XMLHttpRequest} * @returns {XMLHttpRequest}
*/ */
httpGet: function httpGet(url, callback, self) { httpGet: function httpGet(url, params, self) {
let params = callback; if (callable(params))
if (!isObject(params)) // Deprecated.
params = { callback: params && ((...args) => callback.apply(self, args)) }; params = { callback: params.bind(self) };
try { try {
let xmlhttp = services.Xmlhttp(); let xmlhttp = services.Xmlhttp();
@@ -761,8 +761,8 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
let async = params.callback || params.onload || params.onerror; let async = params.callback || params.onload || params.onerror;
if (async) { if (async) {
xmlhttp.addEventListener("load", function handler(event) { util.trapErrors(params.onload || params.callback, params, xmlhttp, event); }, false); xmlhttp.addEventListener("load", event => { util.trapErrors(params.onload || params.callback, params, xmlhttp, event); }, false);
xmlhttp.addEventListener("error", function handler(event) { util.trapErrors(params.onerror || params.callback, params, xmlhttp, event); }, false); xmlhttp.addEventListener("error", event => { util.trapErrors(params.onerror || params.callback, params, xmlhttp, event); }, false);
} }
if (isObject(params.params)) { if (isObject(params.params)) {
@@ -810,6 +810,22 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
} }
}, },
/**
* Like #httpGet, but returns a promise rather than accepting
* callbacks.
*
* @param {string} url The URL to fetch.
* @param {object} params Parameter object, as in #httpGet.
*/
fetchUrl: promises.withCallbacks(function fetchUrl([accept, reject, deferred], url, params) {
params = update({}, params);
params.onload = accept;
params.onerror = reject;
let req = this.httpGet(url, params);
promises.oncancel(deferred, req.cancel);
}),
/** /**
* The identity function. * The identity function.
* *
@@ -1555,7 +1571,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
* Waits for the function *test* to return true, or *timeout* * Waits for the function *test* to return true, or *timeout*
* milliseconds to expire. * milliseconds to expire.
* *
* @param {function} test The predicate on which to wait. * @param {function|Promise} test The predicate on which to wait.
* @param {object} self The 'this' object for *test*. * @param {object} self The 'this' object for *test*.
* @param {Number} timeout The maximum number of milliseconds to * @param {Number} timeout The maximum number of milliseconds to
* wait. * wait.
@@ -1565,6 +1581,15 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
* thrown. * thrown.
*/ */
waitFor: function waitFor(test, self, timeout, interruptable) { waitFor: function waitFor(test, self, timeout, interruptable) {
if (!callable(test)) {
let done = false;
var promise = test,
retVal;
promise.then((arg) => { retVal = arg; done = true; },
(arg) => { retVal = arg; done = true; });
test = () => done;
}
let end = timeout && Date.now() + timeout, result; let end = timeout && Date.now() + timeout, result;
let timer = services.Timer(function () {}, 10, services.Timer.TYPE_REPEATING_SLACK); let timer = services.Timer(function () {}, 10, services.Timer.TYPE_REPEATING_SLACK);
@@ -1575,7 +1600,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
finally { finally {
timer.cancel(); timer.cancel();
} }
return result; return promise ? retVal: result;
}, },
/** /**
@@ -1595,7 +1620,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
* @returns {function} A new function which may not execute * @returns {function} A new function which may not execute
* synchronously. * synchronously.
*/ */
yieldable: function yieldable(func) yieldable: deprecated("Task.spawn", function yieldable(func)
function magic() { function magic() {
let gen = func.apply(this, arguments); let gen = func.apply(this, arguments);
(function next() { (function next() {
@@ -1604,7 +1629,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
} }
catch (e if e instanceof StopIteration) {}; catch (e if e instanceof StopIteration) {};
})(); })();
}, }),
/** /**
* Wraps a callback function such that its errors are not lost. This * Wraps a callback function such that its errors are not lost. This