obniz Advent Calendar 2020の16日が開いていたので、
obnizにはobniz.repeat
という便利?関数の布教活動してみます。
obniz.repeat
はあんまりみんなに使われていない気がするんですよね。
obniz.repeatって何?
obniz.repeat
はobnizで繰り返し処理をするときに設定する関数です。
arduinoで言うところのloopですね。
ずっと繰り返してくれる=無限ループだ! ってことで while(true){}
と同じだと思われるんですが、
実ははうらで色々やってて、
- obnizデバイスとの接続が切れたら自動で止まるように
- 内部でエラーが出ても止まらずに次のループを動かしてくれる
という機能もついています
とりあえずコードで比較
↓動くんだけど、のちにハマりやすい書き方
let obniz = new Obniz("XXXXX");
obniz.onconnct = async ()=>{
let led = obniz.wired("LED", {xxxx});
while(true){
led.on();
await obniz.wait(1000);
led.off();
await obniz.wait(1000);
}
}
↓おすすめの書き方
let obniz = new Obniz("XXXXX");
obniz.onconnct = async ()=>{
let led = obniz.wired("LED", {xxxx});
obniz.repeat(async ()=>{
led.on();
await obniz.wait(1000);
led.off();
await obniz.wait(1000);
}, 0); //リピートインターバルが0ms
}
while(true)
とobniz.repeat
の比較です。
書くコード量はどっちもそんなに変わらないし、どちらも同じようにかけます。
ただ、これが途中でデバイスとの接続が切れた!というときに、
while(true)はled.on()がうまく行かなくてthrow
→ try/catchはこのコードで書かれてないので、プログラム全体のエラーとなり、プログラムがクラッシュする
obniz.repeatはthrowをハンドリングして、console.errorに出すだけでクラッシュしなくなる
& 自動で次のループも止めるので正常にプログラムが動き続ける
という違いが生まれます。
とりあえず繰り返し処理したいからwhile(true)
だ!というのを、とりあえずobniz.repeat
だ!に変えるだけで、ちょっとだけ安全なプログラムになるので、ぜひ使ってください
オプション
obniz.repeatには第2引数があって、インターバル時間を指定できます。
repeatの第1引数で指定した関数を実行するときに、ちょっと待つってことができます。
一番高速で動かしたければゼロを指定すればOKですが、5分に1度だけ動かしたいなと言うときは5分=300,000msなので300000と指定すればOKです
↓5分に1秒だけ光るLED. タイミング見計らうのが難しそう
let obniz = new Obniz("XXXXX");
obniz.onconnct = async ()=>{
let led = obniz.wired("LED", {xxxx});
obniz.repeat(async ()=>{
led.on();
await obniz.wait(1000);
led.off();
}, 300000); //リピートインターバルが300000ms = 5min
}
ライフサイクル
ちなみに、全体的な挙動イメージはこんなライフサイクルになります。
右側に書いてるのはobniz.connectionStateで取れる値です。
obniz.onconnect = async () => {}
でプログラムを書いている人が大半だと思いますが、実はobniz.on('connect', async ()=>{})
って書き方でもOKだったり・・・!
プログラムの書き方Tipsはそのうちまた記事にしようと思います。