ひtoりgoと

JXA で Promise

MacDev

Yosemite から AppleScript の代わりに使える JXA、せっかく JavaScript なのだから Promise が使えるかどうか実験してみよう。

const getWindowNames = async (appName) => {
    const app = new Application(appName);
    const windows = app.windows;
    return windows.name();
}
const getFileNames = async (path) => {
    const fileManager = $.NSFileManager.defaultManager;
    let error = $();
    const fileUrls = fileManager.contentsOfDirectoryAtURLIncludingPropertiesForKeysOptionsError($.NSURL.fileURLWithPath(path), [], 0, error);
    return fileUrls.js.map(url => url.lastPathComponent.js);
}

let x = null;
Promise.all([
    getFileNames("/System"),
    getWindowNames("Finder"),
    getWindowNames("Calendar")
]).then((result, error) => {
    x = result;
});

const runLoop = $.NSRunLoop.currentRunLoop;
while (x === null) {
    runLoop.runModeBeforeDate($.NSRunLoopCommonModes, $.NSDate.dateWithTimeIntervalSinceNow(0.001))
    console.log("a")
}
x
Code

Promise の完了を待つように Run Loop を回しているのがポイント。これがないとすぐに終了してしまうし、ただのループだとずっとぐるぐる、何も起きない。スクリプトエディタ内で気軽に動かしたいだけなので idle ハンドラは試さず。 

関数を定義するときに async も使ってみたけど、どうだろう。

結果

[[".localized", "iOSSupport", "Library"], ["Downloads"], ["Calendar", "", "", ""]]
Result

動いた! 実行前に必ずコンパイルし直さないとエラーが出たりしてスクリプトエディタの挙動が怪しいものの、動かないわけではないようだ。

ただしメリットは特になさそう... マルチスレッドで分散できるわけでもないし。

本日の「だからなんだ」案件1でした。


  1. 現実逃避したいだけ ↩︎

Share

リンクも共有もお気軽に。記事を書くモチベーションの向上に役立てます。

© 2005-2020 zumuya