コードの挙動がわからないときは、ログ出力をしてみましょう。
たくさん出力しすぎるとかえって分かりにくくなるので注意が必要ですが。
JavaScript以外の言語でも、ログ出力ができるときは有効です。
JavaScript
1var countdown = function(count) {
2 console.log('countdown(' + count + ')開始!!');
3 var argCount = count; // 引数countが変化するために保存
4
5 console.log(count--);
6
7 console.log('次にsetTimeout開始 count:' + count);
8
9 var tid = setTimeout(function(){
10 countdown(count); // 再帰
11 }, 500);
12
13 console.log('setTimeoutからreturn!! tid: ' + tid + ' count:' + count);
14
15 if (count < 0) {
16 clearTimeout(tid);
17 console.log('clearTimeout(' + tid + ')からreturn!!');
18 }
19
20 console.log('次にcountdown(' + argCount + ')からreturn');
21};
22countdown(10);
23console.log("終了");
ログ解析:
countdown(10)開始!!
10
次にsetTimeout開始 count:9
setTimeoutからreturn!! tid: 82 count:9
次にcountdown(10)からreturn
終了
undefined
countdown(9)開始!!
9
次にsetTimeout開始 count:8
setTimeoutからreturn!! tid: 83 count:8
次にcountdown(9)からreturn
countdown(8)開始!!
8
次にsetTimeout開始 count:7
setTimeoutからreturn!! tid: 84 count:7
次にcountdown(8)からreturn
countdown(7)開始!!
:
中略
:
countdown(1)開始!!
1
次にsetTimeout開始 count:0
setTimeoutからreturn!! tid: 91 count:0
次にcountdown(1)からreturn
countdown(0)開始!!
0
次にsetTimeout開始 count:-1
setTimeoutからreturn!! tid: 92 count:-1
clearTimeout(92)からreturn!!
次にcountdown(0)からreturn
再帰呼び出しによってcountdown(9)が開始される前に、
「setTimeoutからreturn」、「countdown(10)からreturn」していることがわかります。
そのために、「終了」がこのタイミングで表示されました。
期待していた結果を得る為には、同じようにログを見ると、
「clearTimeout(92)からreturn!!」の直後に
「console.log("終了");」を移動すればよいことがわかります。
よって、
JavaScript
1var countdown = function(count) {
2 console.log(count--);
3 var tid = setTimeout(function(){
4 countdown(count); // 再帰
5 }, 500);
6 if (count < 0) {
7 clearTimeout(tid);
8 console.log("終了");
9 }
10};
11countdown(10);
ただし、コンソールによって、「10」の表示直後に、
countdown(10)の戻り値「undefined」が自動表示されることがあります。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/05/28 07:52
2017/05/28 07:55