js: Promisify async operations
Promises make asynchronous operations easier to manage, in particular when used through the async/await syntax that allows for asynchronous code to closely resemble synchronous one. gjs has included a Gio._promisify() helper for a while now, which monkey-patches methods that follow GIO's async pattern to return a Promise when called without a callback argument. Use that to get rid of all those GAsyncReadyCallbacks! https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1126
This commit is contained in:

committed by
Florian Müllner

parent
18742fcc32
commit
764527c8c9
@@ -10,6 +10,7 @@ const MessageTray = imports.ui.messageTray;
|
||||
const ModalDialog = imports.ui.modalDialog;
|
||||
const ShellEntry = imports.ui.shellEntry;
|
||||
|
||||
Gio._promisify(Shell.NetworkAgent.prototype, 'init_async', 'init_finish');
|
||||
Gio._promisify(Shell.NetworkAgent.prototype,
|
||||
'search_vpn_plugin', 'search_vpn_plugin_finish');
|
||||
|
||||
@@ -482,39 +483,37 @@ var VPNRequestHandler = class {
|
||||
}
|
||||
}
|
||||
|
||||
_readStdoutOldStyle() {
|
||||
this._dataStdout.read_line_async(GLib.PRIORITY_DEFAULT, null, (stream, result) => {
|
||||
let [line, len_] = this._dataStdout.read_line_finish_utf8(result);
|
||||
async _readStdoutOldStyle() {
|
||||
const [line, len_] =
|
||||
await this._dataStdout.read_line_async(GLib.PRIORITY_DEFAULT, null);
|
||||
|
||||
if (line == null) {
|
||||
// end of file
|
||||
this._stdout.close(null);
|
||||
return;
|
||||
}
|
||||
if (line === null) {
|
||||
// end of file
|
||||
this._stdout.close(null);
|
||||
return;
|
||||
}
|
||||
|
||||
this._vpnChildProcessLineOldStyle(line);
|
||||
this._vpnChildProcessLineOldStyle(line);
|
||||
|
||||
// try to read more!
|
||||
this._readStdoutOldStyle();
|
||||
});
|
||||
// try to read more!
|
||||
this._readStdoutOldStyle();
|
||||
}
|
||||
|
||||
_readStdoutNewStyle() {
|
||||
this._dataStdout.fill_async(-1, GLib.PRIORITY_DEFAULT, null, (stream, result) => {
|
||||
let cnt = this._dataStdout.fill_finish(result);
|
||||
async _readStdoutNewStyle() {
|
||||
const cnt =
|
||||
await this._dataStdout.fill_async(-1, GLib.PRIORITY_DEFAULT, null);
|
||||
|
||||
if (cnt == 0) {
|
||||
// end of file
|
||||
this._showNewStyleDialog();
|
||||
if (cnt === 0) {
|
||||
// end of file
|
||||
this._showNewStyleDialog();
|
||||
|
||||
this._stdout.close(null);
|
||||
return;
|
||||
}
|
||||
this._stdout.close(null);
|
||||
return;
|
||||
}
|
||||
|
||||
// Try to read more
|
||||
this._dataStdout.set_buffer_size(2 * this._dataStdout.get_buffer_size());
|
||||
this._readStdoutNewStyle();
|
||||
});
|
||||
// Try to read more
|
||||
this._dataStdout.set_buffer_size(2 * this._dataStdout.get_buffer_size());
|
||||
this._readStdoutNewStyle();
|
||||
}
|
||||
|
||||
_showNewStyleDialog() {
|
||||
@@ -621,15 +620,17 @@ var NetworkAgent = class {
|
||||
this._native.connect('cancel-request', this._cancelRequest.bind(this));
|
||||
|
||||
this._initialized = false;
|
||||
this._native.init_async(GLib.PRIORITY_DEFAULT, null, (o, res) => {
|
||||
try {
|
||||
this._native.init_finish(res);
|
||||
this._initialized = true;
|
||||
} catch (e) {
|
||||
this._native = null;
|
||||
logError(e, 'error initializing the NetworkManager Agent');
|
||||
}
|
||||
});
|
||||
this._initNative();
|
||||
}
|
||||
|
||||
async _initNative() {
|
||||
try {
|
||||
await this._native.init_async(GLib.PRIORITY_DEFAULT, null);
|
||||
this._initialized = true;
|
||||
} catch (e) {
|
||||
this._native = null;
|
||||
logError(e, 'error initializing the NetworkManager Agent');
|
||||
}
|
||||
}
|
||||
|
||||
enable() {
|
||||
|
@@ -7,6 +7,14 @@ var Tpl = null;
|
||||
var Tp = null;
|
||||
try {
|
||||
({ TelepathyGLib: Tp, TelepathyLogger: Tpl } = imports.gi);
|
||||
|
||||
Gio._promisify(Tp.Channel.prototype, 'close_async', 'close_finish');
|
||||
Gio._promisify(Tp.Channel.prototype,
|
||||
'send_message_async', 'send_message_finish');
|
||||
Gio._promisify(Tp.ChannelDispatchOperation.prototype,
|
||||
'claim_with_async', 'claim_with_finish');
|
||||
Gio._promisify(Tpl.LogManager.prototype,
|
||||
'get_filtered_events_async', 'get_filtered_events_finish');
|
||||
} catch (e) {
|
||||
log('Telepathy is not available, chat integration will be disabled.');
|
||||
}
|
||||
@@ -215,7 +223,7 @@ class TelepathyClient extends Tp.BaseClient {
|
||||
|
||||
// We can only handle text channel, so close any other channel
|
||||
if (!(channel instanceof Tp.TextChannel)) {
|
||||
channel.close_async(null);
|
||||
channel.close_async();
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -261,7 +269,7 @@ class TelepathyClient extends Tp.BaseClient {
|
||||
}
|
||||
}
|
||||
|
||||
_approveTextChannel(account, conn, channel, dispatchOp, context) {
|
||||
async _approveTextChannel(account, conn, channel, dispatchOp, context) {
|
||||
let [targetHandle_, targetHandleType] = channel.get_handle();
|
||||
|
||||
if (targetHandleType != Tp.HandleType.CONTACT) {
|
||||
@@ -270,17 +278,15 @@ class TelepathyClient extends Tp.BaseClient {
|
||||
return;
|
||||
}
|
||||
|
||||
// Approve private text channels right away as we are going to handle it
|
||||
dispatchOp.claim_with_async(this, (o, result) => {
|
||||
try {
|
||||
dispatchOp.claim_with_finish(result);
|
||||
this._handlingChannels(account, conn, [channel], false);
|
||||
} catch (err) {
|
||||
log('Failed to Claim channel: %s'.format(err.toString()));
|
||||
}
|
||||
});
|
||||
|
||||
context.accept();
|
||||
|
||||
// Approve private text channels right away as we are going to handle it
|
||||
try {
|
||||
await dispatchOp.claim_with_async(this);
|
||||
this._handlingChannels(account, conn, [channel], false);
|
||||
} catch (err) {
|
||||
log('Failed to Claim channel: %s'.format(err.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
_delegatedChannelsCb(_client, _channels) {
|
||||
@@ -441,17 +447,14 @@ class ChatSource extends MessageTray.Source {
|
||||
}
|
||||
}
|
||||
|
||||
_getLogMessages() {
|
||||
async _getLogMessages() {
|
||||
let logManager = Tpl.LogManager.dup_singleton();
|
||||
let entity = Tpl.Entity.new_from_tp_contact(this._contact, Tpl.EntityType.CONTACT);
|
||||
|
||||
logManager.get_filtered_events_async(this._account, entity,
|
||||
Tpl.EventTypeMask.TEXT, SCROLLBACK_HISTORY_LINES,
|
||||
null, this._displayPendingMessages.bind(this));
|
||||
}
|
||||
|
||||
_displayPendingMessages(logManager, result) {
|
||||
let [success_, events] = logManager.get_filtered_events_finish(result);
|
||||
const [events] = await logManager.get_filtered_events_async(
|
||||
this._account, entity,
|
||||
Tpl.EventTypeMask.TEXT, SCROLLBACK_HISTORY_LINES,
|
||||
null);
|
||||
|
||||
let logMessages = events.map(e => ChatMessage.newFromTplTextEvent(e));
|
||||
this._ensureNotification();
|
||||
@@ -509,9 +512,7 @@ class ChatSource extends MessageTray.Source {
|
||||
this._ackMessages();
|
||||
// The chat box has been destroyed so it can't
|
||||
// handle the channel any more.
|
||||
this._channel.close_async((channel, result) => {
|
||||
channel.close_finish(result);
|
||||
});
|
||||
this._channel.close_async();
|
||||
} else {
|
||||
// Don't indicate any unread messages when the notification
|
||||
// that represents them has been destroyed.
|
||||
@@ -609,9 +610,7 @@ class ChatSource extends MessageTray.Source {
|
||||
}
|
||||
|
||||
let msg = Tp.ClientMessage.new_text(type, text);
|
||||
this._channel.send_message_async(msg, 0, (src, result) => {
|
||||
this._channel.send_message_finish(result);
|
||||
});
|
||||
this._channel.send_message_async(msg, 0);
|
||||
}
|
||||
|
||||
setChatState(state) {
|
||||
|
Reference in New Issue
Block a user