ES6 Promise

ES6 には Promise という非同期関数がある。

Promiseと仲良くなって気持ち良く非同期処理を書こう – Qiita

なるほど、Promise 関数と then 関数を使えばいいのか。
てなわけで、毎度のようにコイツで GUI アプリを起動してみよう。

#!/usr/bin/gjs

const GLib = imports.gi.GLib;

function asyncFunction(guiApp) {
    return new Promise(function (resolve, reject) {
        print("__DO__");
        GLib.spawn_command_line_sync(guiApp);
        resolve("__DONE__");
    });
}

asyncFunction("eog")
    .then(function (value) {
        print(value);
    })
    .catch(function (error) {
        print(error);
    });

print("__EOL__");

だめヤン!
非同期ならこの状態で __EOL__ まで抜けているはずだ。

で、昨日気が付いたんだけど思い込みによる勘違いだった。
非同期になるのは Promise 関数内ではなく then 関数内であるようだ。

#!/usr/bin/gjs

const GLib = imports.gi.GLib;

function asyncFunction() {
    return new Promise(function (resolve, reject) {
        resolve(null);
    });
}

print("__START__");

asyncFunction()
    .then(function (value) {
        GLib.spawn_command_line_sync("eog");
    });

print("__EOL__");

コレなら __EOL__ まで抜けているのにアプリは実行されたままになる。
GUI アプリを起動するコードだと動作を把握しやすい、Linux の長所。

んで、実は単純な非同期処理なら省略表記があって。

#!/usr/bin/gjs

const GLib = imports.gi.GLib;

Promise.resolve(null).then(function (value) {
    GLib.spawn_command_line_sync("eog");
});

print("__EOL__");

以上。

超シンプルな非同期処理のできあがり。
Promise 関数は前処理で then が非同期の実行という解釈でいいかな。
前処理(確認作業)が不要なら省略表記で、と使い分けできるね。

アロー関数を使えばクラスメソッドも問題なく使えるようだ。

#!/usr/bin/gjs

const GLib = imports.gi.GLib;

class PromiseTest {
    get command() {return this._command;}
    set command(cmd) {this._command = cmd;}
    asyncFunc() {
        Promise.resolve(null).then((value)=> {
            GLib.spawn_command_line_sync(this.command);
        });
    }
}

let test = new PromiseTest();
test.command = "evince";
test.asyncFunc();

print("__EOL__");

ES6 フル活用!

えぇ… JavaScript !!!
と記法で超嫌っていた JavaScript が今ではこんなに面白いとは予測できなかったYO!