ほんじゃらねっと

ダイエット中プログラマのブログ

node.jsがやたら非同期化しようとするのをasync/awaitでどうにか同期化する

Node.jsは入出力関連の処理を非同期で行ないます。入出力イベントが非同期で実行されることで、遅い入出力処理の合間に他の処理を挟んで効率的にプログラムを実行することができます。この特長を活かすため、ライブラリに含まれる関数も非同期的に実行されるものがとても多いです。

簡単に処理を非同期化できるようになっているというのはうまく活用できれば大変ありがたいもので、node.jsの最大の特長だと言えます。

ところがただ「簡単に導入できて」「実行速度が速くて」「Javascriptで書ける」ツールとして手軽にnode.jsを使いたい、という場合にこの非同期至上主義なところが邪魔をすることがあります。

ちょっとした処理を行うコマンドラインスクリプトをサクッと作りたいだけなのに、思ったような順番で処理が実行されなかったり、コールバック地獄になったり。

同期的に動かそうとするだけでなぜこんなに分かりにくい書き方をしなければならないのか...。プログラミング初心者がnode.jsを使おうとした時に頭を悩ませる大変の要因はこの非同期処理の同期化によるものではないでしょうか。

せっかく簡単に導入できてJavascriptで書けて実行速度も速い最高のツールなのに、自分には合わない、とnode.jsを捨ててしまうのはもったいないです。

Node.jsのv7.6から導入された「async/await」を使うことで同期化がしやすくなり、慣れ親しんだものに近い形でプログラムが書けるようになりました。一度使ってみるとこれ無しではやってられなくなるくらいすっきりとしたコードが書けます。

今回はこの「async/awaitを用いた非同期処理の同期化」の方法について紹介します。

「async/await」を使用すると呼び出し側のコードがスッキリする

async/awaitはどういう機能かを乱暴に説明すると、「非同期な関数」に「async」というキーワードをつけておくことで非同期的にでも同期的にでも呼べるようにする機能です。「await」キーワード付でasync関数を呼ぶことで、あたかも同期的な処理を行う関数であるかのように扱えます。

コールバック型の非同期関数とasync/await型の非同期関数の定義と呼び出しのちがいを比較しながら見てみましょう。

非同期な関数はいつ実行が終了するか分からないので、引数として関数の処理完了後に実行する処理をまとめたコールバック関数を渡しておき、それを実行させます。非同期な関数が実行完了してから実行したい処理がある場合はコールバック関数の中に書くことになります。

望む実行順で非同期関数を実行したい場合はコールバック関数の中で非同期関数を呼び出し、そのコールバック関数の中でまた別の非同期関数を呼び出し、という風にコールバック関数が何重にも入れ子になった状態になります。これがいわゆる「コールバック地獄」というやつです。

仮にコールバック型の非同期関数「asyncReadValueCallbackFunc」が下記のように定義されているとしましょう。

function asyncReadValueCallbackFunc(params, callbackFunc) {
    // ...非同期な処理...
   result = ...;

   // 処理が終わってからcallback関数に処理結果を渡す。
    callbackFunc(result);
}

asyncReadValueCallbackFuncは下記のように呼んで使用します。

function main() {
    console.log('呼び出し前');

    asyncReadValueCallbackFunc('パラメータ', function (res) {
        console.log('asyncReadValueCallbackFunc実行後に実行したいコード');
        console.log(result);
    });

    console.log('呼び出し後');
}

この場合、「呼び出し後」というメッセージを出力する処理はasyncReadValueCallbackFuncの実行完了を待たずに実行されるので、「asyncReadValueCallbackFunc実行後に実行したいコード」の出力とどちらが先に実行されるかは実行してみないと分かりません。確実にasyncReadValueCallbackFuncの後に実行したい処理はコールバック関数内に記述します。

コールバック地獄になるとこんな感じのコードになります。

function main() {
    console.log('呼び出し前');

    asyncCallbackFunc1('パラメータ', function (result1) {
        console.log('asyncCallbackFunc1実行後に実行したいコード');

        asyncCallbackFunc2(result1, function (result2) {
            console.log('asyncCallbackFunc2実行後に実行したいコード');

            asyncCallbackFunc3(result2, function (result3) {
                console.log('asyncCallbackFunc3実行後に実行したいコード');
                console.log(result3);
            });
        });
    });

    console.log('呼び出し後');
}

最終的にresult3の計算結果を出すためにasyncCallbackFunc1〜3を順に実行しています。それぞれの関数は意図したとおりの順序で実行されますが、コードが非常に分かりづらいです。

async/awaitを使うと、非同期関数の処理結果をコールバック関数で受け取る代わりに戻り値として受け取ることができます。上記のasyncReadValueCallbackFuncと同じ処理をasync/awaitを用いて行う関数「asyncReadValueFunc」を実装してみましょう。

async function asyncReadValueFunc(params) {
    // ...非同期な処理...
    result = ...;

    // resultを実行結果として返す        
    return result;
}

コールバック関数を受け取るパラメータが不要となり、代わりに「async」というキーワードをfunction定義前に追加しています。

このasyncReadValueFuncは下記のように呼んで使用します。

async function main() {
    console.log('呼び出し前');

    const res = await asyncReadValueFunc('パラメータ');
    console.log('asyncReadValueFunc実行後に実行したいコード');
    console.log(result);

    console.log('呼び出し後');
}

呼び出す側はasyncReadValueFuncを呼び出す際に「await」というキーワードをつけていますが、それ以外は同期関数を呼び出すのと同じ形式で関数を呼んでいます。main関数を実行すると、「呼び出し前」「asyncReadValueFunc実行後に実行したいコード」「resultの値」「呼び出し後」の順で出力されます。

awaitをつけるだけで、コールバック関数を仕込んだりする必要がなく、普通の非同期でない関数と同じように結果を受け取ることができるわけです。

上述のコールバック地獄のサンプルをasync/await版に書き換えてみましょう。

async function main() {
    console.log('呼び出し前');

    const result1 = await asyncAwaitFunc1('パラメータ');
    console.log('asyncAwaitFunc1実行後に実行したいコード');

    const result2 = await asyncAwaitFunc2(result1);
    console.log('asyncAwaitFunc2実行後に実行したいコード');

    const result3 = await asyncAwaitFunc3('パラメータ');
    console.log('asyncAwaitFunc3実行後に実行したいコード');
    console.log(result3);

    console.log('呼び出し後');
}

実にスッキリしたコードになります。

asyncキーワードは関数の戻り値をPromiseオブジェクトに変換する

単純にasync/awaitを使うのは割と簡単です。上の例で見たとおり、asyncキーワード付で宣言された関数であれば、awaitキーワード付で呼び出すだけで同期的に使用することができます。

これだけでも便利に使えるのですが、更に使いこなすためには裏で何が行われているのかを知っておきましょう。

たとえば、非同期関数の前にasyncをつけることで、つける前と何が変わるのでしょう?

答えは、「asyncをつけるとreturnした値がPromiseオブジェクトに変換される」です。async関数とは、必ずPromiseオブジェクトを返す関数なのです。

PromiseはJavascriptに組み込まれた機能の1つで、async/awaitと同じく非同期処理を管理しやすくするためのものです。実際のところasyncとawaitはあくまでPromiseをより簡単に利用するために後から追加された機能であり、Promiseこそが主役なのです。

ではそのPromiseとは何かというと、これまた乱暴に説明すると「非同期処理を1つのオブジェクトにまとめて持ち回しやすくするもの」だと言えます。

ファイルの読み込みなり書き込みなりの時間のかかる入出力処理を非同期で行いつつ、完了した後で別の処理を行いたいと言う時に、その非同期処理ごと1つのPromiseオブジェクトにまとめてしまって、どこでも結果を受け取れるようにしよう、というものです。

Promiseを使うことで、非同期処理を実行する関数にコールバック関数を渡す代わりに、戻り値としてまだ中で非同期処理を実行しているPromiseオブジェクトを返す、ということができるようになります。

developer.mozilla.org

Promiseオブジェクトを返す関数の定義と、その関数を呼び出してPromiseオブジェクトを受け取る処理を見てみましょう。

// Promiseオブジェクトを返す非同期関数
function asyncPromiseFunc() {
    return new Promise(resolve => {
        // ...何かしらの時間がかかる処理...
        const result = ...;

        resolve(result);
    });
}

function main() {
    // 戻り値のpはPromiseオブジェクト
    const p = asyncPromiseFunc();

    // 非同期処理が完了したらthenに渡したコールバック関数の内容が実行される。
    p.then(function (result) {
        console.log(result);
    });
}

asyncPromiseFuncがPromiseオブジェクトを返す非同期関数です。非同期処理はreturnされるPromiseオブジェクト内で実行される。非同期処理の実行結果をどう処理するかはasyncPromiseFunc関数を呼び出した側でPromiseオブジェクトのthenメソッドにコールバック関数を渡すことで定義できます。

コールバック型関数とのちがいは、非同期関数側がコールバック関数について処理をする必要がなくなり、Promiseオブジェクトを返すだけで良くなった、というところです。また、「非同期処理はPromiseオブジェクトで扱う」という風に統一されることで、async/awaitのような形に発展させやすくなりました。

async関数の話に戻りましょう。

asyncキーワードは上記のPromiseオブジェクトを返す関数を簡単に定義できるようにするものです。

下記の2つの関数は同じようなPromiseオブジェクトを返します。

function asyncPromiseFunc1() {
    return new Promise(resolve => {
        // ...何かしらの時間がかかる処理...
        const result = ...;

        resolve(result);
    });
}

async function asyncPromiseFunc2() {
    // ...何かしらの時間がかかる処理...
    const result = ...;

    return result;
}

function main() {
    const p1 = asyncPromiseFunc1();
    const p2 = asyncPromiseFunc2();

    p1.then(function (result) {
        console.log(result);
    });

    p2.then(function (result) {
        console.log(result);
    });
}

async関数の方は変数を返しているだけのように見えますが、実際はPromiseオブジェクトを生成して返しています。なのでasyncPromiseFunc2を呼び出した側はPromiseオブジェクトを受け取り、thenで処理を定義します。

asyncがPromiseオブジェクトを返す非同期関数の定義を簡単にできるようにするためのものだ、ということが確認できました。

awaitはPromiseオブジェクトの結果を同期的に受け取れるようにする

async関数はPromiseオブジェクトを返す、ではawaitは何をしているのでしょうか?

非同期処理を同期化する、という意味ではどちらかというとasyncよりもawaitの方が重要な役割を担っています。

awaitは渡されたPromiseオブジェクトの実行完了を待って結果を返す機能を持ちます。

awaitを使うことで、コールバック関数を使用することなく直接非同期処理の結果を受け取ることができるわけです。これがあって初めて、コールバック関数無しで非同期処理を順次実行できるようになります。

asyncで書いたサンプルをawaitを使用する形に変更すると、下記のようになります。

function asyncPromiseFunc1() {
    return new Promise(resolve => {
        // ...何かしらの時間がかかる処理...
        const result = ...;

        resolve(result);
    });
}

async function asyncPromiseFunc2() {
    // ...何かしらの時間がかかる処理...
    const result = ...;

    return result;
}

async function main() {
    const result1 = await asyncPromiseFunc1();
    const result2 = await asyncPromiseFunc2();

    console.log(result1);
    console.log(result2);
}

Promiseオブジェクトであれば処理できるので、対象がasync関数なのか、Promiseオブジェクトを直接生成して返す関数なのかは関係ありません。何なら関数ではなく直接Promiseオブジェクトを渡してもちゃんと処理してくれます。

まとめついでに、色々なパターンの非同期処理とその結果を見てみましょう。

// Promiseオブジェクトを返す関数
function p1() {
    return new Promise(resolve => {
        resolve('test1');
    });
}

// Promiseオブジェクトを返すasync関数
async function p2() {
    return new Promise(resolve => {
        resolve('test2');
    });
}

// 値を返す関数
function p3() {
    return 'test3';
}

// 値を返すasync関数
async function p4() {
    return 'test4';
}

async function main() {
    const result11 = p1();
    console.log('result11', result11);

    const result12 = await p1();
    console.log('result12', result12);

    const result21 = p2();
    console.log('result21', result21);

    const result22 = await p2();
    console.log('result22', result22);

    const result31 = p3();
    console.log('result31', result31);

    const result32 = await p3();
    console.log('result32', result32);

    const result41 = p4();
    console.log('result41', result41);

    const result42 = await p4();
    console.log('result42', result42);

    const result99 = await new Promise(resolve => {
        resolve('result99');
    });
    console.log('result99', result99);
}

main();

実行結果

result11 Promise { 'test1' }
result12 test1
result21 Promise { <pending> }
result22 test2
result31 test3
result32 test3
result41 Promise { 'test4' }
result42 test4
result99 result99

実行結果で「Promise { ... }」となっているのは、Promiseオブジェクトの状態になっているということです。awaitを介することでPromiseオブジェクトの処理結果が取得されていることが確認できます。

awaitを関数内で使用する場合は必ずその関数がasync指定されている必要があります。ルールとして覚えておきましょう。

async/awaitでは実装できない処理もある

async/awaitは基本的に組み合わせて使うことが多いですが、Promiseを直接使わないとうまく行かない場合もあります。というか自前で非同期処理を実装する場合はasyncではなくPromiseオブジェクトを生成することの方が多いのではないでしょうか。

例えば一定時間処理を停止するsleep関数を作って使いたい時は下記のような関数を作成します。

function sleep(waitMillSeconds: number) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve();
        }, waitMillSeconds);
    });
}

awaitで呼び出せばシンプルにsleep処理を実行できます。

async function main() {
    console.log('開始');

    // 1秒待機
    await sleep(1000);

    console.log('終了');
}

main();

async/awaitの使い方だけでなく、Promiseオブジェクトについても理解しておく必要がある、ということです。

使いたい非同期関数がPromise非対応の場合はラッパー関数でPromise対応できる

最近のライブラリはだいたいPromise形式の返り値に対応しているので、そういったライブラリはthenを使う代わりにasync/awaitを使えばすっきり書けます。

しかしPromiseオブジェクトを返さない、コールバック関数を前提とした関数も多く存在します。こういった関数を便利に使いたい場合は、自分でPromiseオブジェクトを返すラッパー関数を作成します。

例えばファイルを行ごとにリストにして読み込みたい場合は、下記のような関数を定義するとasync/awaitで呼べるようになります。

import fs from 'fs';
import readline from 'readline';

function readFileLines(srcFilePath, encoding) {
    let rs = fs.createReadStream(srcFilePath, {encoding: encoding});
    let rl = readline.createInterface({input: rs});

    return new Promise((resolve, reject) => {
        const lineList = [];
        rl.on('line', (line) => {
            lineList.push(line);
        })
        .on('close', () => {
            resolve(lineList)
        });
    });
}

おわりに

async/awaitを使うと非同期関数を同期的に使うことができます。Promiseオブジェクトやらそれぞれのキーワードの役割やら色々理解しておかないといけない概念は多いですが、使いこなせば実装がスッキリしてnode.jsでの開発が一層楽しくなること間違いなしなので、ぜひ使ってみてください。

OpenCV + Node.js で画像からぬりえ用の線画をつくる

f:id:piro_suke:20190405013029j:plain

画像処理で遊びたいな、と思い立ったので、 以前PythonとOpenCVで作成した画像線画化スクリプトを Node.jsで作成しなおしてみました。

blog.honjala.net

OpenCVはPythonと使うのがやはり一番使いやすいのですが、 Javascript用APIも提供されているので、 Webページ上のJavascriptやNode.jsからでも利用することができます。

docs.opencv.org

しかし試してみるとNode.jsから生でOpenCV.jsを使うのはcanvasを利用することを 前提にしていたりしてなかなか手強く、うまくいかなかったので、 「opencv4nodejs」というライブラリを使うことにしました。

www.npmjs.com

こちらはOpenCVの関数をNode.jsからいい感じで使えるようにしてくれていて、 Pythonで書いた処理をNode.js用に書き換えるだけでサクッと動いてくれました。

作成した画像線画化スクリプトはこんな感じになりました:

Convert Image Files To Line Drawings With OpenCV A ...

「SOURCE_DIRECTORY_PATH」に画像が入ったフォルダを指定して、 「DEST_DIRECTORY_PATH」に出力先フォルダを指定すると、 JPEG画像を一括で線画に変換して出力します。

おわり

これでいろいろOpenCVの機能を使って遊べそうです。

詳解 OpenCV 3 ―コンピュータビジョンライブラリを使った画像処理・認識

詳解 OpenCV 3 ―コンピュータビジョンライブラリを使った画像処理・認識

  • 作者: Gary Bradski,Adrian Kaehler,松田晃一,小沼千絵,永田雅人,花形理
  • 出版社/メーカー: オライリージャパン
  • 発売日: 2018/05/26
  • メディア: 単行本(ソフトカバー)
  • この商品を含むブログを見る

WebアプリとWebサーバをセットにした「ポータブルなWebアプリ」という形でソフトウェアを配布する

先日書いたツールのGUI化に関する記事で

blog.honjala.net

Electronやcarloを使ったデスクトップアプリ化について紹介したあとで

ちょっと考えていた時のこと。

carloのようにUI機能を持たずに

インストールされているChromeを使うのがアリならば、

もう思い切ってWebアプリをそのままexe化して配布するのもアリなのでは!

という閃きが降りてきた。

exe1つで実行できるWebアプリ、名付けて「ポータブルWebアプリ」。

わざわざ専用のGUIアプリを作るのではなく、

Webアプリとそれを実行するWebサーバをそのまま一緒にexe化して提供し、

操作はブラウザ経由で行なってもらう。

Webプログラマにとってはメリットしかない

carloと同じく、UI部分をブラウザが担ってくれるので、exeのサイズも抑えられる。

carloとちがって実行してから別途ブラウザからアクセスする必要はあるけど、

Chrome以外のブラウザでも使える。

プログラムとしては普通のWebアプリを作って、そのままパッケージングするだけ。

クラウドサーバを借りて管理する必要もなく、

exeをブログ等からダウンロードできるようにして配布する。

Webアプリは作れるけど、サーバ管理面倒、

でもGUIアプリの作り方覚えるのも面倒、そんな方にもぴったり。

ユーザーにもメリット

さらにアプリを利用する側からみても、

通常のGUIアプリと比較して大きなメリットがある。

それはLAN経由でスマホやらタブレットからもアクセスできちゃう!ということ。

言ってみれば単なるローカルWebサーバなので。

個人や家族で使いたいツールやゲームを提供するには完璧な配布方法ではなかろうか。

作ってみた

自分の思いつきに興奮した勢いでちょっとしたネットワーク対戦ゲームを作ってみた。

2〜4人のプレイヤーでそれぞれ自分の色のブロックを守りながら

他のプレイヤーのブロックを壊す、「ブロックホッケー」。

プログラムの内容としては、

Node.jsのExpress + socket.io でWebSocket対応のWebサーバを立てて、

フロントにVue.js + Vuetifyを使った、構成としては普通のWebアプリ。

それをpkgでパッケージングしてexe化したもの。

exeを実行すると、コンソールが立ち上がってアクセス可能なURLが表示される。

ブラウザからアクセスすると、名前と色を入力して人数が集まってからゲームスタート。

試す時はブラウザを2つ立ち上げてアクセスするといい感じで動くはず。

(一人でスタートすると一瞬でゲーム終了します)

https://pirosuke.github.io/games/block-hockey/socket-server-win.exe

f:id:piro_suke:20181201002422p:plain

おわり:昔からあったわ

考えてみたらローカルWebサーバを使うアプリって昔からあった。

でもそれがとても簡単に実現できて、

Webプログラマにとって楽な配布方法であることは間違いないので、

この形式で配布したら面白いアプリを考えてみたい。

node.jsでWebスクレイピングして取得データを保存する

node.jsでデータ収集のためのWebスクレイピングを行う。

Webスクレイピングの流れというのはだいたい決まっていて、

  1. WebページにアクセスしてHTMLを取得する
  2. 取得したHTMLの中から必要なデータを抽出する
  3. 抽出したデータを保存する

の3段階となる。

続きを読む

node.jsでリモートのLinux環境やデータベースの操作を自動化する

ぼくが仕事でLinuxサーバ環境に接続して行う操作というのはだいたい決まっていて、

  • コマンドでサーバの状態を確認
  • ログをファイル出力してダウンロード
  • サービスの設定変更と再起動
  • SSHトンネル経由でDBアクセス

のうちどれかを行うことが多い。

基本は手作業だったり、シェルスクリプトを作って

実行したりする形で対応できるものなのだけど、

結構めんどくさいので、

今回はnode.jsでどこまで自動化できるかを試してみたい。

続きを読む

デザイナーとプログラマのわがままに応えて、テンプレートエンジンから生成されたHTMLファイルを元の部品ファイルに分割するツールを作る

f:id:piro_suke:20170529005556j:plain

Webアプリを開発する際、

最近の多くのテンプレートエンジンはHTMLをレイアウトや部品に分割して作成し、

それをextendしたりincludeしたりして1つのHTMLとして出力できるようになっている。

部品化することで、ヘッダーとかメニューとかフッターとか、

複数のページで共通して表示する要素を変更する際に、

1箇所だけ変更すれば済むようになるわけだ。

しかし部品化することで発生するデメリットもあって、

Webアプリとして実行してみないと完成版のHTMLが確認できない、

外部のデザイナーさんとデザインをやりとりしづらい、

といった問題が発生する。

続きを読む

Node.jsで非同期処理を不特定回数繰り返す方法をYouTubeのお気に入りタイトル一覧を取得するスクリプトを作りながら考える

f:id:piro_suke:20161212004436j:plain

YouTubeでお気に入りに入れた動画のタイトルを一覧化して見たくなったので、

YouTube Data API経由でデータを取得して表示するNode.jsスクリプトを作ってみた。

APIへのアクセス自体はサクッとできたのだけど、

複数ページデータを非同期で取得するフローのコントロールで苦労した。

Node.jsスクリプトを書く時は毎回このフローコントロールでつまづくのだけど、

慣れの問題なのだろうか。

今回はcaolan/asyncライブラリのおかげで何とか解決できた感じ。

async - Documentation

作成したスクリプトの内容を紹介しつつ、

非同期処理を不特定回数実行する際のパターンについて考えてみよう。

続きを読む

Node.jsでメモリを使い切らずに大容量ファイルを読み込んでデータベースに登録する方法

サーバが重いけどどこを直せばよいか分からないから調査してくれー、と

Tomcatのでかいアクセスログファイルを渡されたので、

とりあえずデータベースに入れて調査してみるべ、と

ログファイルの内容ををデータベースに取り込むスクリプトを書いてみた。

Node.jsのStreamを全然理解してなかったので、よい勉強になった。

続きを読む

便利なリスト・マップ操作関数を提供してくれるUnderscore.js を使ってJavascriptで文字別出現回数を数えるスクリプトを作成する

Javascriptライブラリの中でも、

Underscore.jsが大変気に入っている。

Underscore.js

each、filter、map、reduce等

リスト操作、マップ操作関連の関数が

100以上含まれたユーティリティライブラリで、

他の言語にあってJavascriptにもあったらいいのにな、

と思うようなものをいい具合に用意してくれている。

作業効率化のための一括処理には欠かせないライブラリだ。

今回はUnderscore.jsに含まれるcountBy関数を使って

文字別出現回数取得関数を作ってみる。

続きを読む

Node.jsでWebサイトの更新チェックを自動化する

f:id:piro_suke:20160501015354j:plain

特定のWebサイトを定期的にチェックして特定のキーワードが含まれていたら

通知してくれる仕組みを1つ覚えておくと色々重宝する。

例えば

会社に社員用Webサイトがあるなら、

(そしてそのサイトがRSSもメール通知も提供してないなら)

そこに「重要」とか「人事」とかのキーワードを含む記事が投稿された時に

通知を受け取れるようにしておけば、

いちいちサイトをチェックしにいかなくても

逃さず確認できる。

また、Webスクレイピングする方法を覚えておけば、

通知を受け取る以外にも、

画面キャプチャの撮影や画像やテキストの収集を

自動化したり、作成したWebシステムの画面テストを行う、

等の応用もしやすくなる。

今回は Node.js + Grunt + cheerio-httpcli を使用して

手軽にWebサイトのデータをチェックする方法を紹介する。

続きを読む

一日使い続けるだけで通信速度が低下する古いルーターを毎日再起動させるNode.jsスクリプト

先日iPad miniとiPhone 6sを導入してから、

うちの古いルーターが2日間隔くらいで再起動しないと

通信が遅くなってネットに繋がらなくなるようになった。

どうやら新しいiPadとiPhoneはWi-fi環境だとガシガシ通信するようで、

ルーターのキャパをすぐに超えてしまうみたいだ。

ルーターを新しくすればすぐに解決しそうな話だが、

とりあえず1日1回再起動すれば快適に使えるようなので、

ルーターを再起動するスクリプトを書いてみた。

続きを読む

Node.jsとGruntでフォルダ監視ツールを作る

f:id:piro_suke:20160414001322j:plain

コミュニケーションというのはなかなか難しいもので、

「急いで確認したいから資料ができたら共有フォルダに入れて、すぐ連絡してよ」

と強めに伝えても、

資料はとっくにできてるのに

やれ後で連絡するつもりだっただの、

もうちょっと確認してから連絡するつもりだっただの、

今メール書いてただので、

一本内線をくれるだけで良いのになかなか連絡がもらえないことがある。

そんなストレスフルな行き違いは

「このやろう!」と毎回怒りを爆発させるよりも

ツールを使って解決の仕組みを用意してしまうに限る。

ということで今回は指定したフォルダを監視して、

ファイルが追加されたり更新されたりしたら

自動で通知してくれるスクリプトをつくってみたい。

続きを読む

正規表現を使ったエレガントな置換処理を学びつつ簡易なファイル名一括変換ツールを作る

文字列を検索したりマッチしたものを置換したり、という作業は

技術者が制作・開発する時だけでなく、例えばExcelやWordで文書を編集する際や

Webページ内で目的の文章を探したりする場合にも行うもので、

「作業の効率化」という点では欠かせないものだ。

今回扱う「正規表現」を使った検索・置換については、

標準の機能として備えているツールやテキストエディタも多いが、

プログラマ以外には馴染みの薄いものかもしれない。

(少なくとも私に面倒な変換作業を依頼してくる人たちは間違いなく知らないと思う)

「正規表現」を全く知らない人は、

このつまらなそうな言葉を見ただけでスルーしてしまいそうだが、

使いこなせば大変強力なものであり

プログラマ以外の

パソコンを使用して何かしらの仕事をしている人にとっても

作業効率が劇的に上がること間違いなしの技術なので、

ここで紹介しておきたい。

続きを読む

プログラミングはしたくないけど自動化はしたい人のための、Grunt.jsによる作業自動化入門

前回書いたNode.js入門記事の続き。

blog.honjala.net

前回から引き続き、

いかにプログラムの勉強無しで自動化できることを増やすか、

もとい、

いかに他部署のノンプログラマに自動化ツールを使わせて自分への作業依頼を減らすか、

をマイテーマに少しずつ情報をまとめていく。

Node.jsを紹介しただけでは、「Javascript…難しそう。いつかやるわ。」

となりそうなので、

今回はプログラミング要素最小限で使えるGruntを紹介する!

続きを読む

作業自動化のための Node.js 入門

これまでいくつかの記事でNode.jsを使ったスクリプトを載せてきたが、

自動化のためのスクリプトを書いて動かす環境として

Node.jsは手軽だし速いし色々ライブラリは揃ってきているし

なかなか良い環境だと感じている。

Web系の仕事をしていればJavascriptはある程度親しみのある言語だろうし、

GruntやGulpのようなWeb関連作業を自動化する

機能満載のタスクランナーまで用意されている。

実行環境もインストーラをダウンロードしてインストールすれば

パッケージ管理ツール付きで入手することができるので、

すぐに開発を始めることができる。

非同期処理が得意なサーバアプリケーションを作るための環境として

紹介されることが多いけど、この手軽に導入できて

Javascriptでサクッとアプリが作れるところだけでも十分に価値があると思う。

ノンプログラマが仕事を効率化するためにプログラミングを始めるなら、

とりあえずNode.jsから始めてみたらいいんじゃないだろうか。

今回はこのブログで紹介しているNode.jsのサンプルを試していただけるよう、

Node.js実行環境のインストールから

簡単なサンプルプログラムを作って実行するところまでを紹介したい。

自分でプログラムを作成するところまでいかなくても、

入手したプログラムを実行できるようになれば自動化作業も捗るのではないかと思う。

続きを読む