teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

2

コメント修正

2021/01/10 11:52

投稿

umau
umau

スコア831

answer CHANGED
@@ -11,7 +11,7 @@
11
11
  // ↓のtmが 「client.on('message', message => { ... });」の外にある事が重要。
12
12
  // setTimeoutしている部分は、内部関数を10秒後に実行するように設定して、そのまま先に進み、
13
13
  // イベント関数は終了します。その時点で、イベント関数内で定義された変数は消えてしまうため、
14
- // tmは外のグローバルな位置に定義しておきます。10秒後起動する関数が見るためです。
14
+ // tmは外のグローバルな位置に定義しておきます。cancel呼び出し時に見るためです。
15
15
  let tm;
16
16
  client.on('message', message => {
17
17
  if (message.author.bot) {

1

内容を簡略化

2021/01/10 11:52

投稿

umau
umau

スコア831

answer CHANGED
@@ -1,47 +1,30 @@
1
1
  中にざっくり説明書きました。
2
+ (1/10 19:47 編集) 簡単な内容に書き換えました
2
3
 
3
4
  ※javascriptの変数のライフサイクル、スコープについて勉強する場合、クロージャというキーワードで検索して勉強してみてください。
4
5
 
5
- ※setTimeoutのところを、setIntervalに変えると、10秒ごとに繰り返し呼び出され、キャンセルされるまで続く、という動きになります。やりたい事はこっちじゃないですかね。
6
-
7
6
  ```
8
7
  client.on('ready', () => {
9
8
  console.log('ready...');
10
9
  });
11
10
 
12
- // ↓のcancelFlgが message => { ... }(以下、イベント関数) の外にある事が重要。
11
+ // ↓のtm「client.on('message', message => { ... });」の外にある事が重要。
13
- // setTimeoutしている部分は、pechakucya関数を10秒後に実行するように設定して、そのまま先に進み、
12
+ // setTimeoutしている部分は、内部関数を10秒後に実行するように設定して、そのまま先に進み、
14
13
  // イベント関数は終了します。その時点で、イベント関数内で定義された変数は消えてしまうため、
15
- // cancelFlgは外のグローバルな位置に定義しておきます。10秒後に起動するpechakucya関数が見るためです。
14
+ // tmは外のグローバルな位置に定義しておきます。10秒後に起動する関数が見るためです。
16
- // 10秒経つ前にcancelメッセージを飛ばすと、cancelFlgがtrueになり、
17
- // pechakucyaが実行された時に「やめ」になります。
18
- let cancelFlg = false
15
+ let tm;
19
-
20
16
  client.on('message', message => {
21
17
  if (message.author.bot) {
22
18
  return;
23
19
  }
24
20
 
25
- let tm;
26
21
  if (message.content === 'start') {
27
-
28
- // tm はイベント関数内に定義されていますが、pechakucha関数の中で使われているため、
29
- // イベント関数終了時に消されず、pechakucyaが参照を持ち続けることになります。
30
- // (詳しくはJavascriptのクロージャについて勉強してください)
31
- tm = setTimeout(function pechakucya(){
22
+ tm = setTimeout(function(){
32
- if (cancelFlg) {
33
- clearTimeout(tm)
34
- message.channel.send('やめ')
35
- return
36
- }
37
23
  message.channel.send('10秒経ったよ')
38
-
39
24
  }, 10000)
40
25
  } else if (message.content === 'cancel') {
26
+ clearTimeout(tm)
41
- // cancelはsetTimeoutの中で行います。
27
+ message.channel.send('やめ')
42
- // ここでclearTimeoutを呼んでも、setTimeout時に設定したtmは残っていないため、
43
- // 止められません。
44
- cancelFlg = true
45
28
  }
46
29
  });
47
30
  client.login(token);