зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1066619 - Accept Promise arguments in PromiseWorker. r=froydnj
This commit is contained in:
Родитель
96ea2fb1a3
Коммит
266846e742
|
@ -242,9 +242,10 @@ this.BasePromiseWorker.prototype = {
|
|||
* Post a message to a worker.
|
||||
*
|
||||
* @param {string} fun The name of the function to call.
|
||||
* @param {Array} args The arguments to pass to `fun`. By convention,
|
||||
* the last argument may be an object `options` with some of the following
|
||||
* fields:
|
||||
* @param {Array} args The arguments to pass to `fun`. If any
|
||||
* of the arguments is a Promise, it is resolved before posting the
|
||||
* message. By convention, the last argument may be an object `options`
|
||||
* with some of the following fields:
|
||||
* - {number|null} outExecutionDuration A parameter to be filled with the
|
||||
* duration of the off main thread execution for this call.
|
||||
* @param {*=} closure An object holding references that should not be
|
||||
|
@ -254,6 +255,11 @@ this.BasePromiseWorker.prototype = {
|
|||
*/
|
||||
post: function(fun, args, closure) {
|
||||
return Task.spawn(function* postMessage() {
|
||||
// Normalize in case any of the arguments is a promise
|
||||
if (args) {
|
||||
args = yield Promise.resolve(Promise.all(args));
|
||||
}
|
||||
|
||||
let id = ++this._id;
|
||||
let message = {fun: fun, args: args, id: id};
|
||||
this.log("Posting message", message);
|
||||
|
|
|
@ -11,3 +11,5 @@ DIRS += [
|
|||
EXTRA_JS_MODULES += [
|
||||
'PromiseWorker.jsm',
|
||||
]
|
||||
|
||||
XPCSHELL_TESTS_MANIFESTS += ['tests/xpcshell/xpcshell.ini']
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
content promiseworker ./
|
|
@ -0,0 +1,30 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Trivial worker definition
|
||||
|
||||
importScripts("resource://gre/modules/workers/require.js");
|
||||
let PromiseWorker = require("resource://gre/modules/workers/PromiseWorker.js");
|
||||
|
||||
let worker = new PromiseWorker.AbstractWorker();
|
||||
worker.dispatch = function(method, args = []) {
|
||||
return Agent[method](...args);
|
||||
},
|
||||
worker.postMessage = function(...args) {
|
||||
self.postMessage(...args);
|
||||
};
|
||||
worker.close = function() {
|
||||
self.close();
|
||||
};
|
||||
worker.log = function(...args) {
|
||||
dump("Worker: " + args.join(" ") + "\n");
|
||||
};
|
||||
self.addEventListener("message", msg => worker.handleMessage(msg));
|
||||
|
||||
let Agent = {
|
||||
bounce: function(...args) {
|
||||
return args;
|
||||
}
|
||||
};
|
|
@ -0,0 +1,65 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
let Cu = Components.utils;
|
||||
|
||||
Cu.import("resource://gre/modules/PromiseWorker.jsm", this);
|
||||
Cu.import("resource://gre/modules/Timer.jsm", this);
|
||||
|
||||
// Worker must be loaded from a chrome:// uri, not a file://
|
||||
// uri, so we first need to load it.
|
||||
|
||||
let WORKER_SOURCE_URI = "chrome://promiseworker/content/worker.js";
|
||||
do_load_manifest("data/chrome.manifest");
|
||||
let worker = new BasePromiseWorker(WORKER_SOURCE_URI);
|
||||
worker.log = function(...args) {
|
||||
do_print("Controller: " + args.join(" "));
|
||||
};
|
||||
|
||||
// Test that simple messages work
|
||||
add_task(function* test_simple_args() {
|
||||
let message = ["test_simple_args", Math.random()];
|
||||
let result = yield worker.post("bounce", message);
|
||||
Assert.equal(JSON.stringify(result), JSON.stringify(message));
|
||||
});
|
||||
|
||||
// Test that it works when we don't provide a message
|
||||
add_task(function* test_no_args() {
|
||||
let result = yield worker.post("bounce");
|
||||
Assert.equal(JSON.stringify(result), JSON.stringify([]));
|
||||
});
|
||||
|
||||
// Test that messages with promise work
|
||||
add_task(function* test_promise_args() {
|
||||
let message = ["test_promise_args", Promise.resolve(Math.random())];
|
||||
let stringified = JSON.stringify((yield Promise.resolve(Promise.all(message))));
|
||||
let result = yield worker.post("bounce", message);
|
||||
Assert.equal(JSON.stringify(result), stringified);
|
||||
});
|
||||
|
||||
// Test that messages with delayed promise work
|
||||
add_task(function* test_delayed_promise_args() {
|
||||
let promise = new Promise(resolve => setTimeout(() => resolve(Math.random()), 10));
|
||||
let message = ["test_delayed_promise_args", promise];
|
||||
let stringified = JSON.stringify((yield Promise.resolve(Promise.all(message))));
|
||||
let result = yield worker.post("bounce", message);
|
||||
Assert.equal(JSON.stringify(result), stringified);
|
||||
});
|
||||
|
||||
// Test that messages with rejected promise cause appropriate errors
|
||||
add_task(function* test_rejected_promise_args() {
|
||||
let error = new Error();
|
||||
let message = ["test_promise_args", Promise.reject(error)];
|
||||
try {
|
||||
yield worker.post("bounce", message);
|
||||
do_throw("I shound have thrown an error by now");
|
||||
} catch (ex if ex == error) {
|
||||
do_print("I threw the right error");
|
||||
}
|
||||
});
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
[DEFAULT]
|
||||
head=
|
||||
tail=
|
||||
support-files=
|
||||
data/worker.js
|
||||
data/chrome.manifest
|
||||
|
||||
[test_Promise.js]
|
Загрузка…
Ссылка в новой задаче