【Javascript】複数の関数を連続して実行する方法を試してみる
へんてこな?ことを試してます。意味不明だったらすみません。
概要
ある文字列が、ある複数の条件を満たしているかどうか判定したい。
1つ1つの条件判定は1つ1つ関数にするのだが、以下の2つの呼び出し方のどちらが速いか。
手順1 - 素直に1つずつ実行
ごく普通の風景。
function fn1(x){return "判定結果";}
function fn2(x){return "判定結果";}
function fn3(x){return "判定結果";}
function fn4(x){return "判定結果";}
function fn5(x){return "判定結果";}
if (fn1(x) && fn2 (x) && fn3(x) && fn4(x) && fn5(x)) {
//全部trueだったらOK
} else {
//ひとつでも途中でfalseだったらNG
}
手順2 - 数珠つながりにしてfn1だけ呼べばよいようにする
関数の配列を作るなどするとおもしろい数珠つながりが作れる(後でやってみる)
function fn1(x){return "判定結果" && fn2(x);}
function fn2(x){return "判定結果" && fn3(x);}
function fn3(x){return "判定結果" && fn4(x);}
function fn4(x){return "判定結果" && fn5(x);}
function fn5(x){return "判定結果";}
if (fn1(x)) {
//trueだったら全部OKということ
} else {
//falseだったら途中でNGがあったということ
}
実際にやりたいことに近いことをやってみる
なぜこんなことをしているかというと、ユーザーの入力に応じて判定条件を変えたいので、臨機応変に判定関数を組み合わせて実行したいから。
以下のサンプルコードの「/1/.test(x)」は、文字列xが文字"1"を含んでいればtrue、含んでいなければfalseが返ってくる(参考:RegExp.test)。
手順1のテスト
//判定関数を用意する(配列に入れておく。順次実行するときはfor文を使うことになる。)
var fn = [];
fn.push(function(x){return /1/.test(x);});
fn.push(function(x){return /2/.test(x);});
fn.push(function(x){return /3/.test(x);});
fn.push(function(x){return /4/.test(x);});
fn.push(function(x){return /5/.test(x);});
//100000回試すテスト
var start = new Date().getTime();
for (var n = 0; n < 100000; ++n) {
var hantei = true;
var x = "123456789";
for (var i = 0, l = fn.length; i < l; ++i) {
if (!fn[i](x)) {
//falseが返ってきたら、判定中止
hantei = false;
break;
}
}
//hantei を見ると判定結果が分かる
}
var end = new Date().getTime();
alert(end - start);
結果 → 328ミリ秒
手順2のテスト
//判定関数を用意する(配列に入れておく。1つ目(fn[0])をキックすると数珠つながりに実行されるように仕掛けておく。)
var fn = [];
fn.push(function(x, i){return /1/.test(x) && fn[i + 1](x, i + 1);});
fn.push(function(x, i){return /2/.test(x) && fn[i + 1](x, i + 1);});
fn.push(function(x, i){return /3/.test(x) && fn[i + 1](x, i + 1);});
fn.push(function(x, i){return /4/.test(x) && fn[i + 1](x, i + 1);});
fn.push(function(x, i){return /5/.test(x);});
//100000回試すテスト
var start = new Date().getTime();
for (var n = 0; n < 100000; ++n) {
var x = "123456789";
var hantei = fn[0](x, 0);
//hantei を見ると判定結果が分かる
}
var end = new Date().getTime();
alert(end - start);
結果 → 296ミリ秒
結果
数珠つながり方式が意外とまともに使えそうだった。
どこかですでに使われているだろうか。