LoginSignup
0

More than 5 years have passed since last update.

[Javascript] ある条件が満たされるまでループする

Last updated at Posted at 2017-02-24

例えば、あるライブラリlib.jsを読み込んだ後にそのライブラリの関数funcに引数[1, 2]を入れて実行したいとする。
その場合以下のように書けばよい。

<!-- 読み込み終わると、グローバル変数 MYLIB にライブラリが代入されるものとする -->
<script async src="lib.js">

<script>
(function loop(args, interval) {
    if(typeof MYLIB !== "undefined") { // ループを抜ける条件を入れる
        return MYLIB.func(args); // func(args); return true; などと書いてもいい
    }
    setTimeout(loop, interval, args);
})([1, 2], 100); // 100ミリ秒ごとにチェックする
</script>

これを一般化すると以下のようになる。

(function loop(args, interval) {
    if(condition) { // ループを抜ける条件を入れる
        return func(args);
    }
    setTimeout(loop, interval, args);
})();

さらに一般化を進め、任意の関数を条件達成後に実行する関数は以下となる。

/**
 * 100ミリ秒毎にライブラリの読み込みが終わったかチェックし、その後関数funcを実行するループを作成する。
 * @param {function} func      ループを抜ける際に実行される関数 
 * @param {function} condition ループを抜ける条件。この関数は true か false を返さなければならない
 * @param {array}    args      func に適用される引数の配列
 * @param {number}   interval  ループする感覚(ミリ秒)
 */
let makeLoop = (func, condition = () => {return true}, args = [], interval = 100) => {
    (function loop() {
        if(condition() === true) {
            return func(args)
        }
        setTimeout(loop, interval, args);
    })();
};


// 読み込み終わると、グローバル変数 MYLIB にライブラリが代入されるものとする
$.getScript("lib.js");

let [f, c, a, i] = [
    (args) => { MYLIB.func(args) }, // Uncaught ReferenceError を回避するため
    () => {
        return typeof MYLIB !== "undefined";
    },
    [1, 2],
    100
];

makeLoop(f, c, a, i); // MYLIB に値が代入された後100ミリ秒以内に MYLIB.func([1, 2]) が実行される

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0