|
@@ -47,6 +47,22 @@ const Cu = Components.utils;
|
|
|
const CB_READY = {};
|
|
|
const CB_COMPLETE = {};
|
|
|
|
|
|
+/**
|
|
|
+ * Create a callback that remembers state like whether it's been called
|
|
|
+ */
|
|
|
+function makeCallback() {
|
|
|
+ // The main callback remembers the value it's passed and that it got data
|
|
|
+ let onComplete = function Sync_onComplete(data) {
|
|
|
+ onComplete.value = data;
|
|
|
+ onComplete.state = CB_COMPLETE;
|
|
|
+ };
|
|
|
+
|
|
|
+ // Initialize the callback to wait to be called
|
|
|
+ onComplete.state = CB_READY;
|
|
|
+
|
|
|
+ return onComplete;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* Make a synchronous version of the function object that will be called with
|
|
|
* the provided thisArg.
|
|
@@ -55,39 +71,22 @@ const CB_COMPLETE = {};
|
|
|
* The asynchronous function to make a synchronous function
|
|
|
* @param thisArg {Object} [optional]
|
|
|
* The object that the function accesses with "this"
|
|
|
+ * @param callback {Function} [optional] [internal]
|
|
|
+ * The callback that will trigger the end of the async. call
|
|
|
* @usage let ret = Sync(asyncFunc, obj)(arg1, arg2);
|
|
|
* @usage let ret = Sync(ignoreThisFunc)(arg1, arg2);
|
|
|
* @usage let sync = Sync(async); let ret = sync(arg1, arg2);
|
|
|
*/
|
|
|
-function Sync(func, thisArg) {
|
|
|
- // Create a callback that remembers its state
|
|
|
- let makeCallback = function Sync_makeCallback() {
|
|
|
- // The main callback remembers the value it's passed and that it got data
|
|
|
- let onComplete = function Sync_onComplete(data) {
|
|
|
- onComplete.value = data;
|
|
|
- onComplete.state = CB_COMPLETE;
|
|
|
- };
|
|
|
-
|
|
|
- // Initialize the callback to wait to be called
|
|
|
- onComplete.state = CB_READY;
|
|
|
-
|
|
|
- return onComplete;
|
|
|
- };
|
|
|
-
|
|
|
- // If the sync. function callback is extracted, remember what it is
|
|
|
- let extractedCallback;
|
|
|
-
|
|
|
- let syncFunc = function Sync_syncFunc(/* arg1, arg2, ... */) {
|
|
|
+function Sync(func, thisArg, callback) {
|
|
|
+ return function syncFunc(/* arg1, arg2, ... */) {
|
|
|
// Grab the current thread so we can make it give up priority
|
|
|
let thread = Cc["@mozilla.org/thread-manager;1"].getService().currentThread;
|
|
|
|
|
|
// Save the original arguments into an array
|
|
|
let args = Array.slice(arguments);
|
|
|
|
|
|
- // Track the callback used for this sync. invocation instance
|
|
|
- let instanceCallback = extractedCallback;
|
|
|
-
|
|
|
- // We need to add a callback if it wasn't extracted out beforehand
|
|
|
+ let instanceCallback = callback;
|
|
|
+ // We need to create a callback and insert it if we weren't given one
|
|
|
if (instanceCallback == null) {
|
|
|
// Create a new callback for this invocation instance and pass it in
|
|
|
instanceCallback = makeCallback();
|
|
@@ -107,20 +106,23 @@ function Sync(func, thisArg) {
|
|
|
// Return the value passed to the callback
|
|
|
return instanceCallback.value;
|
|
|
};
|
|
|
-
|
|
|
- // Grabbing the onComplete converts the sync. function to not assume the first
|
|
|
- // argument is our custom callback
|
|
|
- syncFunc.__defineGetter__("onComplete", function() {
|
|
|
- // Only allow one callback to be made, so delete the getter immediately
|
|
|
- delete syncFunc.onComplete;
|
|
|
-
|
|
|
- // Remember the one callback made as a property and locally
|
|
|
- return syncFunc.onComplete = extractedCallback = makeCallback();
|
|
|
- });
|
|
|
-
|
|
|
- return syncFunc;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * Make a synchronous version of an async. function and the callback to trigger
|
|
|
+ * the end of the async. call.
|
|
|
+ *
|
|
|
+ * @param func {Function}
|
|
|
+ * The asynchronous function to make a synchronous function
|
|
|
+ * @param thisArg {Object} [optional]
|
|
|
+ * The object that the function accesses with "this"
|
|
|
+ * @usage let [sync, cb] = Sync.withCb(async); let ret = sync(arg1, arg2, cb);
|
|
|
+ */
|
|
|
+Sync.withCb = function Sync_withCb(func, thisArg) {
|
|
|
+ let cb = makeCallback();
|
|
|
+ return [Sync(func, thisArg, cb), cb];
|
|
|
+};
|
|
|
+
|
|
|
/**
|
|
|
* Set a timer, simulating the API for the window.setTimeout call.
|
|
|
* This only simulates the API for the version of the call that accepts
|