

どのように実装すべきなのかわからなかいので質問させていただきます。

下のコードは、現在時刻を垂れ流すwebsocketサーバに接続するコードです。  
「関数Xを登録しそれを毎分N秒に実行する。ただし毎時間M分で登録を解除する」といったことをしたい場合どのように実装すべきでしょうか？

一応自分で書いてみたのですが、awaitで処理が完了するのを待てなかったり、コールバック地獄になるようなコードになってしまうので助言をいただきたいと思います。

[code]

    const ws = new WebSocket('wss://websocketstest.com/service');
    ws.onopen = () => {
        ['connected,', 'version,hybi-draft-13', 'echo,test message', 'timer,']
            .forEach(c=>ws.send(c));
    };
    
    let events = []
    ws.onmessage = (blob) => {
            if (events.length === 0) return;
            const messageDate = new Date(blob.data.split(',')[1]);
            for (const event of events) {
                if (event.func(messageDate) === true) {
                    event.valid = false;
                }
            }
            events = events.filter(s => s.valid === true);
    }
    
    function register(func) {
        events.push({
            func: func,
            valid: true
        });
    }
    
    const N = 30;
    const M = 5;
    const X = ()=>{console.log("FOFOOOOOO");};
    (async () => {
        register(msg => {
            console.log(msg);
            if (msg.getSeconds() % N === 0) {
                X()
            }
            if (msg.getHours() % M === 0) {
                return true; // 終了
            }
        });
        console.log('end');
    })();
    
[/code]


CC BY-SA 3.0
2017-09-23T09:44:29.507
38141
2020-04-19T07:01:55.153
2017-09-24T07:46:45.283
24648
24648
question
javascript
JavaScriptの処理を登録するパターンについて


Observer/Observableのパターンで作ればいいのではないかと思います。ObserverはObservableに登録して、Observableは任意のタイミングで登録者にメッセージを送ります。

[DEMO](https://jsfiddle.net/fbL4cark/2/)

[code]

    ws.onopen = () => {
        ['connected,', 'version,hybi-draft-13', 'echo,test message', 'timer,']
            .forEach(c=>ws.send(c));
    };
    
[/code]

この部分はよく分からなかったのでそのままにしときました。

> awaitで処理が完了するのを待てなかったり

`await`は`Promise`オブジェクトに対してしか使えないので、今の場合自分でわざわざ`Promise`を返すような関数を作る必要がありますが、別に使わなくていいと思います。

> コールバック地獄になるようなコードになってしまう

今の場合コールバックの連鎖が必要ないので callback hell にはならないと思います。


CC BY-SA 3.0
2017-09-24T16:07:38.567
38158
2017-09-24T16:07:38.567
20206
38141
answer


元々のコードが色々と入り組んでいますが以下のような感じではダメなのでしょうか？

[code]

    ws.onmessage = (blob) => {
      const msg = new Date(blob.data.split(',')[1]);
      if (msg.getMinutes() < M) {
        if (msg.getSeconds() === S) { X(); }
      }
    }
    
[/code]


CC BY-SA 4.0
2019-03-03T13:36:46.063
53172
2019-03-03T13:36:46.063
4388
38141
answer