summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvi Zajac <avirzajac@gmail.com>2018-08-16 18:34:40 -0700
committerAvi Zajac <avirzajac@gmail.com>2018-08-19 15:27:00 -0700
commitdecae6d1c98c0b073eed23fe4b7b0481a127d9b2 (patch)
tree6952e3309e9add3ab84b30d7dd6972d2680b38de
parentfe12be991408c1c4b9f1b5649f331eb9ae336520 (diff)
downloadgjs-decae6d1c98c0b073eed23fe4b7b0481a127d9b2.tar.gz
Added _promisify to GJS GIO overrides
The _promisify function is a new internal feature for GJS, providing developers the option to write asynchronous operations with either the original callbacks from GNOME's original C (using GObject) libraries or to write them using async/await, a new modern way to write asynchronous code in JavaScript. This feature hides all of the original callbacks from developers in a Promise, allowing one to call the _async function like a variable by calling it with await in an async function. This is a backwards compatible feature, thus it will not impact already existing code using callbacks. Please note that if you use this feature, to be ready for the official API version coming out in 3.32 where slight changes to your code will be necessary (in a good way, you can remove an extra line or two of your code)! To use this feature, instead of nesting your _async and _finish function in your code (e.g. load_contents_async, load_contents_finish), you can update your program to an "async function", and call the _async function with an await leading it. You will also need to call the feature in your program, too, until the 3.32 release. Example: Gio._promisify(..., 'load_contents_async', 'load_contents_finish'); let [raw_content] = file.load_contents_async(cancellable);
-rw-r--r--modules/overrides/Gio.js28
1 files changed, 28 insertions, 0 deletions
diff --git a/modules/overrides/Gio.js b/modules/overrides/Gio.js
index 23a0648e..f6f02054 100644
--- a/modules/overrides/Gio.js
+++ b/modules/overrides/Gio.js
@@ -343,6 +343,31 @@ function* _listModelIterator() {
}
}
+function _promisify(proto, asyncFunc, finishFunc) {
+ proto[`_original_${asyncFunc}`] = proto[asyncFunc];
+ proto[asyncFunc] = function(...args) {
+ if (!args.every(arg => typeof arg !== 'function'))
+ return this[`_original_${asyncFunc}`](...args);
+ return new Promise((resolve, reject) => {
+ const callStack = new Error().stack.split('\n').filter(line => !line.match(/promisify/)).join('\n');
+ this[`_original_${asyncFunc}`](...args, function(source, res) {
+ try {
+ const result = source[finishFunc](res);
+ if (Array.isArray(result) && result.length > 1 && result[0] === true)
+ result.shift();
+ resolve(result);
+ } catch (error) {
+ if (error.stack)
+ error.stack += `### Promise created here: ###\n${callStack}`;
+ else
+ error.stack = callStack;
+ reject(error);
+ }
+ });
+ });
+ };
+}
+
function _init() {
Gio = this;
@@ -401,4 +426,7 @@ function _init() {
// ListStore
Gio.ListStore.prototype[Symbol.iterator] = _listModelIterator;
+
+ // Promisify
+ Gio._promisify = _promisify;
}