日別アーカイブ: 2017/07/27

Node.js Gjs Async

今回は Node.js でシェルコマンドを使う方法を探してみる。

Node.jsからシェルコマンドを実行する – BppLOG

あらこんな簡単に、Gjs と違って日本語で見つかるのは羨ましい。
exec で非同期になるのかフムフム。

…って非同期通信だよね、mainloop いらないの?
関数を抜けた後でも callback handler を保持しなきゃいけないよね??
本当は非同期ではないのかも、実験だ!

#!/usr/bin/env node

const exec = require('child_process').exec;

exec('eog', (err, stdout, stderr) => {
    if (err) { console.log(err); }
    console.log('callback');
});

console.log('__done__');

GUI のほうが動作が解りやすいので eog を立ち上げてみる、Linux の長所だね。
macOS では Kivy とか PyObjC を使えばいいと思う。
結果は見事に __done__ のほうが先に表示、eog 終了時に callback 表示となった。
見事に関数を抜けているね、本当に非同期で動いていことを確認できた。
どうやっているの?

っっって。
よく見たら child_process というモジュール名じゃないか。
つまり Subprocess で動かしているだけってことかも。
Gjs で同様に動く処理を考えてみる、えぇと…

#!/usr/bin/gjs

const Gio = imports.gi.Gio;
const ByteArray = imports.byteArray;

let subprocess = Gio.Subprocess.new(["ls", "-la"], Gio.SubprocessFlags.STDIN_PIPE);
let barray = new ByteArray.ByteArray();
subprocess.communicate_async(barray, null, function(source_object, res) {
    let istream = source_object.get_stdout_pipe();
    let dstream = Gio.DataInputStream.new(istream);
    for (;;) {
        let [s, l] = dstream.read_line_utf8(null);
        if (s == null) break;
        print(s);
    }
});
print('__done__');

コチラは上記リンク先同様になるよう ls -la の結果を表示の例。
うん、__done__ のほうが先に表示されるので非同期になっている。
つまり Node.js の exec は純粋な非同期ではなく子プロセスってことみたい。

初心者には意味不明?んなモン知るか!!!

いやいや、Node.js をやったおかげで GSubprocess の新たな使い方を知ってしまった。
これで Gjs プログラミングが捗るゾイ!