Commit decae6d1 authored by Avi's avatar Avi

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);
parent fe12be99
Pipeline #25807 passed with stages
in 17 minutes and 49 seconds
......@@ -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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment