Re: 関数をとめる
あけましておめでとうございます、すぎたです。
本年もよろしくお願いいたします。
# 最近忙しくて、あまりアクセスできてないですが、(^^;;
# 時々見ています。
In message news:vKWzd.120$qv2.83@news1.dion.ne.jp
"ITAHASHI Kunio" <kunitahashi@h2.dion.ne.jp> wrote ...
> >if (nr<20) {setTimeOut('F()',100);}
> なるほど。
> システム関数自体に条件をつけることもできるわけですね。
というより、処理したい順に実行されるように、条件によって
処理を分岐して処理内容を変えているということです。
| var nr = 0
| function F(){
| document.all('id1').innerHTML = nr++;
| setTimeout('F()',100);
| }
| nrが20になったときに関数を無効にしたいのです。
上記の例だと、関数 F() は
1) id1 の内容に nr を代入した後、nr に 1 を加える。
2) 100ミリ秒後に関数 F() を呼び出すように、システムに登録する。
となります。
ここで、nr が 20 になったときに関数を無効にするということは、
「nr が 20 になったとき、100ミリ秒後に関数 F() を呼び出すように
システムに登録することを止める」と言えます。
nr が 20 になったときというのが、id1 に 20 が代入されたら
ということだとすると、代入後 1 が加算されて 20 を超えますので、
1) id1 の内容に nr を代入した後、nr に 1 を加える。
2) もし nr が 20 以下だったら、
100ミリ秒後に関数 F() を呼び出すように、システムに登録する。
そうでなかったら(20を超えていたら)
なにもしない(システムに登録しない)
となり、これを JavaScript になおすと、
var nr = 0;
function F() {
document.all('id1').innerHTML = nr++;
if (nr <= 20) {
setTimeout('F()',100);
} else {
}
}
となり、else { } は処理内容が無いので、
if (nr <= 20) {
setTimeout('F()',100);
}
となります。
> var nf = 20;
> var ng = 0;
>
> function G(){
> if(ng<=21){
> document.all('id1').innerHTML = ++ng;
> setTimeout('G()',500);
> if(ng==21){F();}
> }
> }
>
> function F(){
> if(nf>=0){
> document.all('id1').innerHTML = --nf;
> setTimeout('F()',500);
> if(nf==0){G();}
> }
> }
>
>
> 発想は単純なんですが、折り返してきて-1で止まって
> しまいます。どこがいけないのでしょうか。
これも、処理された内容を追うことで、なぜ止まってしまうかが
理解できる…と言いたいところですが、ちょっとややこしいこと
になっています。
まず、初期状態で nf=20, ng=0 となっており、最初に G() が
呼び出されることから、
もし ng が 21 以下であれば、
ng に 1 加算して、id1 に ng を代入する。
500ミリ秒後に 関数 G() を呼び出すように、システムに登録する。
もし ng が 21 と等しかったら、
関数 F() を呼び出す。
そうでなかったら(ng が 21 と等しくなかったら)、
なにもしない。
そうでなかったら(ng が 21 を超えていたら)、
なにもしない
にしたがって、
1) ng が 0 で、21 以下なので、1 を加算し id1 に代入。
2) 500ミリ秒後に 関数 G() を呼び出すように、システムに登録。
3) ng が 1 で、21 と等しくないため、なにもしない。
4) 500ミリ秒後に 関数 G() が呼び出される。
5) ng が 1 で、21 以下なので、1 を加算し id1 に代入。
6) 500ミリ秒後に 関数 G() を呼び出すように、システムに登録。
7) ng が 2 で、21 と等しくないため、なにもしない。
8) 500ミリ秒後に 関数 G() が呼び出される。
......
78) ng が 19 で、21 以下なので、1 を加算し id1 に代入。
79) 500ミリ秒後に 関数 G() を呼び出すように、システムに登録。
80) ng が 20 で、21 と等しくないため、なにもしない。
81) 500ミリ秒後に 関数 G() が呼び出される。
82) ng が 20 で、21 以下なので、1 を加算し id1 に代入。
83) 500ミリ秒後に 関数 G() を呼び出すように、システムに登録。
84) ng が 21 で、21 と等しいため、関数 F() を呼び出す。
85) nf が 20 で、0 以上のなので、1 減算して id1 に代入。
83) 500ミリ秒後に 関数 F() を呼び出すように、システムに登録。
84) nf が 19 で、0 と等しくないため、なにもしない。
85) 500ミリ秒後に 関数 G() が呼び出される。
86) ng が 21 で、21 以下なので、1 を加算し id1 に代入。
87) 500ミリ秒後に 関数 G() を呼び出すように、システムに登録。
88) ng が 22 で、21 と等しくないため、なにもしない。
89) 83) で登録した 関数 F() が呼び出される。
90) nf が 19 で、0 以上のなので、1 減算して id1 に代入。
91) 500ミリ秒後に 関数 F() を呼び出すように、システムに登録。
92) nf が 18 で、0 と等しくないため、なにもしない。
93) 500ミリ秒後に、87) で登録した 関数 G() が呼び出される。
94) ng が 22 で、21 を超えているため、なにもしない。
97) 91) で登録した 関数 F() が呼び出される。
98) nf が 18 で、0 以上のなので、1 減算して id1 に代入。
99) 500ミリ秒後に 関数 F() を呼び出すように、システムに登録。
100) nf が 17 で、0 と等しくないため、なにもしない。
101) 500ミリ秒後に 関数 F() が呼び出される。
......
166) nf が 1 で、0 以上のなので、1 減算して id1 に代入。
167) 500ミリ秒後に 関数 F() を呼び出すように、システムに登録。
168) nf が 0 で、0 と等しいため、関数 G() が呼び出される。
169) ng が 22 で、21 を超えているため、なにもしない。
170) 500ミリ秒後に 関数 F() が呼び出される。
171) nf が 0 で、0 以上なので、1 減算して id1 に代入。
172) 500ミリ秒後に 関数 F() を呼び出すように、システムに登録。
173) nf が 0 で、0 と等しいくないため、なにもしない。
174) 500ミリ秒後に 関数 F() が呼び出される。
175) nf が -1 で、0 未満のため、なにもしない。
のように動作しています。
(ここはちょっとややこしいことになってるので、あまり詳しく
見なくても良いかもしれません)
問題点は2つあって、関数 G() と F() が二重に動作している
個所があることと、F() から G() に移るとき、ng が初期化
されずに 22 のままのため、169) でなにもせずに G() の動作
が停止している点です。
動作を G() と F() に分ける場合、
関数 G()
もし ng が 20 未満であれば、
ng に 1 を加算して、id1 に代入する。
500ミリ秒後に 関数 G() が呼び出されるように、システムに登録。
そうでなければ(20 以上であれば)、
nf を 20 に初期化。
関数 F() を呼び出す。
関数 F()
もし nf が 0 より大きければ、
nf を 1 減算して、id1 に代入する。
500ミリ秒後に 関数 F() が呼び出されるように、システムに登録。
そうでなければ(0 以下であれば)、
ng を 0 に初期化。
関数 G() を呼び出す。
とすることで、
ng=0,G(),0,1,2,...,19,20,nf=20,F(),19,18,...,1,0,ng=0,G(),...
と、連続して動作することになります。
ここで重要なのは、相手の関数の動作に必要な条件を整えておく点で、
F() を呼び出すときは、変数 nf をあらかじめ初期化し、
G() を呼び出すときは、変数 ng をあらかじめ初期化する点です。
初期化には他の方法もあるのですが、本ケースでは、各関数の
を呼び出す前に初期化するのがわかりやすいかと思います。
--
杉田
sugi-nws@bk.iij4u.or.jp
Fnews-brouse 1.9(20180406) -- by Mizuno, MWE <mwe@ccsf.jp>
GnuPG Key ID = ECC8A735
GnuPG Key fingerprint = 9BE6 B9E9 55A5 A499 CD51 946E 9BDC 7870 ECC8 A735