回答編集履歴

2

根本的に質問文を取り違えてたので修正

2017/11/21 12:00

投稿

miyabi-sun
miyabi-sun

スコア21158

test CHANGED
@@ -34,10 +34,6 @@
34
34
 
35
35
 
36
36
 
37
- 質問文を JavaScript / Node.js 流儀で書き直すとこんな感じ。
38
-
39
-
40
-
41
37
  ```JavaScript
42
38
 
43
39
  flag = 0; // global - 他の部分で状態が変化する
@@ -58,15 +54,37 @@
58
54
 
59
55
 
60
56
 
61
- 今回は30秒後に起動した際、「ありゃ、フラグが0から変更されてるじゃん…起動やめよっと」と
57
+ 30秒後に起動した際、「ありゃ、フラグが0から変更されてるじゃん…起動やめよっと」と
62
58
 
63
59
  判断して内部の処理を取りやめるフローに変更しています。
64
60
 
65
61
 
66
62
 
63
+ ---
64
+
65
+
66
+
67
+ 【ここから追記】
68
+
69
+
70
+
71
+ > sleep中であってもflagの値が変化したらsleepをやめるものです。
72
+
73
+
74
+
75
+ つまり、スリープをやめて今すぐ発火して欲しいのですね。
76
+
77
+ 私の上の回答文ではやりたい事は満たせないですね……
78
+
79
+ そのように作り変えましょう!
80
+
81
+
82
+
67
83
  setTimeoutの戻り値のIDを利用して、下記の様に登録したsetTimeoutを取り消す事も可能です。
68
84
 
69
- ただし何時取り消すかに関しては難しい判断にりますの、厳密にる場合一工夫必要かと思います
85
+ つまり登録はしておいたけどやっぱりキャンセル可能です
86
+
87
+ 後で使うので覚えておいてください。
70
88
 
71
89
 
72
90
 
@@ -80,33 +98,23 @@
80
98
 
81
99
 
82
100
 
83
- ---
84
-
85
-
86
-
87
- 追記: 俺はflag変数が変更されたらすぐに取り下げたいんだ!!
88
-
89
-
90
-
91
- MobXというパッケージを導入しましょう。
101
+ そしてMobXというパッケージを導入しましょう。
92
-
93
- おそらくこの縛りでは最善です。
94
102
 
95
103
  参考サイト: [これからMobXをはじめる人へ](http://lealog.hateblo.jp/entry/2016/12/15/113825)
96
104
 
97
105
 
98
106
 
99
- のパッケージはReactという動的なページを表示するフレームワークのおまけみたいな扱いをされますが、
107
+ MobXのパッケージはReactという動的なページを表示するフレームワークのおまけみたいな扱いをされますが、本質は変数のオブザーバにあります。
100
108
 
101
- 本質は変数のオブザーバにあります。
102
-
103
- オブザーバってあれですよ、変数を常に監視して、値が変わったら処理を行う奴です。
109
+ オブザーバというのは変数を常に監視して、値が変わったら即座に関数行するデザインパターンを指します
104
110
 
105
111
 
106
112
 
107
- シチュエーション、flagという変数をひたら見張って変更た瞬間に待機を停止したいのでよね?
113
+ 30秒後に登録しておいたsetTimeout数を取り下げつつ、今ぐ実行
108
114
 
115
+ 因みにMobXに限らず自分で作ったイベントエミッター系は同期実行なのでsetTimeoutに割り込まれる事はなく、
116
+
109
- これ以上の選択肢は無いって過言でりません。
117
+ 30秒同時にフラグが経って2回関数が叩かれるという残念な事起こりません。
110
118
 
111
119
 
112
120
 
@@ -132,6 +140,20 @@
132
140
 
133
141
  });
134
142
 
143
+
144
+
145
+ const fn = function() {
146
+
147
+ if (state.id == null) return;
148
+
149
+ state.id = null;
150
+
151
+ // do something
152
+
153
+ }
154
+
155
+ state.id = setTimeout(fn, 31000);
156
+
135
157
  reaction(
136
158
 
137
159
  () => store.flag,
@@ -140,25 +162,13 @@
140
162
 
141
163
  if (store.flag === 0) return;
142
164
 
143
- clearTimeout(state.id);
165
+ if (state.id) clearTimeout(state.id); // 先程実行したものを取り下げて
166
+
167
+ fn(); // 手動実行!
144
168
 
145
169
  }
146
170
 
147
171
  )
148
-
149
-
150
-
151
- var s = 30;
152
-
153
- var fn = function() {
154
-
155
- if (flag != 0) return;
156
-
157
- // dosomething
158
-
159
- }
160
-
161
- state.id = setTimeout(fn, s * 1000);
162
172
 
163
173
  ```
164
174
 

1

MobXを利用するように修正

2017/11/21 12:00

投稿

miyabi-sun
miyabi-sun

スコア21158

test CHANGED
@@ -77,3 +77,91 @@
77
77
  clearTimeout(fnId);
78
78
 
79
79
  ```
80
+
81
+
82
+
83
+ ---
84
+
85
+
86
+
87
+ 追記: 俺はflag変数が変更されたらすぐに取り下げたいんだ!!
88
+
89
+
90
+
91
+ MobXというパッケージを導入しましょう。
92
+
93
+ おそらくこの縛りでは最善です。
94
+
95
+ 参考サイト: [これからMobXをはじめる人へ](http://lealog.hateblo.jp/entry/2016/12/15/113825)
96
+
97
+
98
+
99
+ このパッケージはReactという動的なページを表示するフレームワークのおまけみたいな扱いをされますが、
100
+
101
+ 本質は変数のオブザーバにあります。
102
+
103
+ オブザーバってあれですよ、変数を常に監視して、値が変わったら処理を行う奴です。
104
+
105
+
106
+
107
+ このシチュエーション、flagという変数をひたすら見張って変更した瞬間に待機を停止したいのですよね?
108
+
109
+ これ以上の選択肢は無いと言って過言ではありません。
110
+
111
+
112
+
113
+ 以前私が[イベントループを上手く回す為にベンチマークと称して使ってたコード](https://github.com/miyabisun/node-queue-benchmark/blob/master/test/MobX.js)がありますので、
114
+
115
+ 流用してサクッと実装してみましょう。
116
+
117
+
118
+
119
+ ```JavaScript
120
+
121
+ const {observable, autorun, reaction} = require('mobx');
122
+
123
+ global.state = {
124
+
125
+ id: null
126
+
127
+ };
128
+
129
+ global.store = observable({
130
+
131
+ flag: 0 // globalのflag変数はこっちに引っ越しました。少し使い勝手が変わるので注意
132
+
133
+ });
134
+
135
+ reaction(
136
+
137
+ () => store.flag,
138
+
139
+ () => {
140
+
141
+ if (store.flag === 0) return;
142
+
143
+ clearTimeout(state.id);
144
+
145
+ }
146
+
147
+ )
148
+
149
+
150
+
151
+ var s = 30;
152
+
153
+ var fn = function() {
154
+
155
+ if (flag != 0) return;
156
+
157
+ // dosomething
158
+
159
+ }
160
+
161
+ state.id = setTimeout(fn, s * 1000);
162
+
163
+ ```
164
+
165
+
166
+
167
+ ざっとこんな感じですかね。