Bug 1371895 - Support legacy Task.jsm generators in DeferredTask.jsm. r=florian

This ensures legacy add-on compatibility by loading Task.jsm lazily when required. Once Task.jsm is removed, this code can be changed back to support only async functions.

MozReview-Commit-ID: 15nY8yArNlZ

--HG--
extra : rebase_source : 129fc4958730fb85176dbb26131cce79e531d41f
This commit is contained in:
Paolo Amadini 2017-06-12 16:42:47 +01:00
Родитель 724db42a49
Коммит b336d5e13d
2 изменённых файлов: 47 добавлений и 2 удалений

Просмотреть файл

@ -90,6 +90,8 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Promise",
"resource://gre/modules/Promise.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Task",
"resource://gre/modules/Task.jsm");
const Timer = Components.Constructor("@mozilla.org/timer;1", "nsITimer",
"initWithCallback");
@ -272,7 +274,7 @@ this.DeferredTask.prototype = {
runningDeferred.resolve((async () => {
// Execute the provided function asynchronously.
await (this._taskFn() || Promise.resolve()).then(null, Cu.reportError);
await this._runTask();
// Now that the task has finished, we check the state of the object to
// determine if we should restart the task again.
@ -284,7 +286,7 @@ this.DeferredTask.prototype = {
// property should return false while the task is running, and should
// remain false after the last execution terminates.
this._armed = false;
await (this._taskFn() || Promise.resolve()).then(null, Cu.reportError);
await this._runTask();
}
}
@ -293,4 +295,20 @@ this.DeferredTask.prototype = {
this._runningPromise = null;
})().then(null, Cu.reportError));
},
/**
* Executes the associated task and catches exceptions.
*/
async _runTask() {
try {
let result = this._taskFn();
if (Object.prototype.toString.call(result) == "[object Generator]") {
await Task.spawn(result); // eslint-disable-line mozilla/no-task
} else {
await result;
}
} catch (ex) {
Cu.reportError(ex);
}
},
};

Просмотреть файл

@ -185,6 +185,33 @@ add_test(function test_arm_async() {
});
});
/**
* Checks that "arm" accepts a Task.jsm generator function.
*/
add_test(function test_arm_async_generator() {
let deferredTask = new DeferredTask(function*() {
yield Promise.resolve();
run_next_test();
}, 50);
deferredTask.arm();
});
/**
* Checks that "arm" accepts a Task.jsm legacy generator function.
*/
add_test(function test_arm_async_legacy_generator() {
// ESLint cannot parse legacy generator functions, so we need an eval block.
/* eslint-disable no-eval */
let deferredTask = new DeferredTask(eval(`(function() {
yield Promise.resolve();
run_next_test();
})`), 50);
/* eslint-enable no-eval */
deferredTask.arm();
});
/**
* Checks that an armed task can be disarmed.
*/