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

回答編集履歴

2

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

2017/11/21 12:00

投稿

miyabi-sun
miyabi-sun

スコア21510

answer CHANGED
@@ -16,8 +16,6 @@
16
16
  Sleepの代わりにやりたいことを予め関数として用意しておいて、
17
17
  setTimeoutという関数と同時に利用します。
18
18
 
19
- 質問文を JavaScript / Node.js 流儀で書き直すとこんな感じ。
20
-
21
19
  ```JavaScript
22
20
  flag = 0; // global - 他の部分で状態が変化する
23
21
  var s = 30;
@@ -28,31 +26,37 @@
28
26
  setTimeout(fn, s * 1000);
29
27
  ```
30
28
 
31
- 今回は30秒後に起動した際、「ありゃ、フラグが0から変更されてるじゃん…起動やめよっと」と
29
+ 30秒後に起動した際、「ありゃ、フラグが0から変更されてるじゃん…起動やめよっと」と
32
30
  判断して内部の処理を取りやめるフローに変更しています。
33
31
 
32
+ ---
33
+
34
+ 【ここから追記】
35
+
36
+ > sleep中であってもflagの値が変化したらsleepをやめるものです。
37
+
38
+ つまり、スリープをやめて今すぐ発火して欲しいのですね。
39
+ 私の上の回答文ではやりたい事は満たせないですね……
40
+ そのように作り変えましょう!
41
+
34
42
  setTimeoutの戻り値のIDを利用して、下記の様に登録したsetTimeoutを取り消す事も可能です。
35
- ただし、何時取消すかに関してしい判断になますの、厳密にる場合一工夫必要かと思います
43
+ つま、登録はしておたけどやっぱキャンセルは可能なんです
44
+ 後で使うので覚えておいてください。
36
45
 
37
46
  ```JavaScript
38
47
  var fnId = setTimeout(fn, s * 1000);
39
48
  clearTimeout(fnId);
40
49
  ```
41
50
 
42
- ---
43
-
44
- 追記: 俺はflag変数が変更されたらすぐに取り下げたいんだ!!
45
-
46
- MobXというパッケージを導入しましょう。
51
+ そしてMobXというパッケージを導入しましょう。
47
- おそらくこの縛りでは最善です。
48
52
  参考サイト: [これからMobXをはじめる人へ](http://lealog.hateblo.jp/entry/2016/12/15/113825)
49
53
 
50
- のパッケージはReactという動的なページを表示するフレームワークのおまけみたいな扱いをされますが、
54
+ MobXのパッケージはReactという動的なページを表示するフレームワークのおまけみたいな扱いをされますが、本質は変数のオブザーバにあります。
51
- 本質は変数のオブザーバにあります。
52
- オブザーバってあれですよ、変数を常に監視して、値が変わったら処理を行う奴です。
55
+ オブザーバというのは変数を常に監視して、値が変わったら即座に関数行するデザインパターンを指します
53
56
 
54
- このシチュエーション、flagとう変数をひたら見張って変更た瞬間に待機を停止したいのでよね?
57
+ 30秒後に登録しておたsetTimeoutの関数を取り下げつつ、今ぐ実行
58
+ 因みにMobXに限らず自分で作ったイベントエミッター系は同期実行なのでsetTimeoutに割り込まれる事はなく、
55
- これ以上の選択肢は無いって過言でりません。
59
+ 30秒同時にフラグが経って2回関数が叩かれるという残念な事起こりません。
56
60
 
57
61
  以前私が[イベントループを上手く回す為にベンチマークと称して使ってたコード](https://github.com/miyabisun/node-queue-benchmark/blob/master/test/MobX.js)がありますので、
58
62
  流用してサクッと実装してみましょう。
@@ -65,20 +69,21 @@
65
69
  global.store = observable({
66
70
  flag: 0 // globalのflag変数はこっちに引っ越しました。少し使い勝手が変わるので注意
67
71
  });
72
+
73
+ const fn = function() {
74
+ if (state.id == null) return;
75
+ state.id = null;
76
+ // do something
77
+ }
78
+ state.id = setTimeout(fn, 31000);
68
79
  reaction(
69
80
  () => store.flag,
70
81
  () => {
71
82
  if (store.flag === 0) return;
72
- clearTimeout(state.id);
83
+ if (state.id) clearTimeout(state.id); // 先程実行したものを取り下げて
84
+ fn(); // 手動実行!
73
85
  }
74
86
  )
75
-
76
- var s = 30;
77
- var fn = function() {
78
- if (flag != 0) return;
79
- // dosomething
80
- }
81
- state.id = setTimeout(fn, s * 1000);
82
87
  ```
83
88
 
84
89
  ざっとこんな感じですかね。

1

MobXを利用するように修正

2017/11/21 12:00

投稿

miyabi-sun
miyabi-sun

スコア21510

answer CHANGED
@@ -37,4 +37,48 @@
37
37
  ```JavaScript
38
38
  var fnId = setTimeout(fn, s * 1000);
39
39
  clearTimeout(fnId);
40
- ```
40
+ ```
41
+
42
+ ---
43
+
44
+ 追記: 俺はflag変数が変更されたらすぐに取り下げたいんだ!!
45
+
46
+ MobXというパッケージを導入しましょう。
47
+ おそらくこの縛りでは最善です。
48
+ 参考サイト: [これからMobXをはじめる人へ](http://lealog.hateblo.jp/entry/2016/12/15/113825)
49
+
50
+ このパッケージはReactという動的なページを表示するフレームワークのおまけみたいな扱いをされますが、
51
+ 本質は変数のオブザーバにあります。
52
+ オブザーバってあれですよ、変数を常に監視して、値が変わったら処理を行う奴です。
53
+
54
+ このシチュエーション、flagという変数をひたすら見張って変更した瞬間に待機を停止したいのですよね?
55
+ これ以上の選択肢は無いと言って過言ではありません。
56
+
57
+ 以前私が[イベントループを上手く回す為にベンチマークと称して使ってたコード](https://github.com/miyabisun/node-queue-benchmark/blob/master/test/MobX.js)がありますので、
58
+ 流用してサクッと実装してみましょう。
59
+
60
+ ```JavaScript
61
+ const {observable, autorun, reaction} = require('mobx');
62
+ global.state = {
63
+ id: null
64
+ };
65
+ global.store = observable({
66
+ flag: 0 // globalのflag変数はこっちに引っ越しました。少し使い勝手が変わるので注意
67
+ });
68
+ reaction(
69
+ () => store.flag,
70
+ () => {
71
+ if (store.flag === 0) return;
72
+ clearTimeout(state.id);
73
+ }
74
+ )
75
+
76
+ var s = 30;
77
+ var fn = function() {
78
+ if (flag != 0) return;
79
+ // dosomething
80
+ }
81
+ state.id = setTimeout(fn, s * 1000);
82
+ ```
83
+
84
+ ざっとこんな感じですかね。