フィヨルドブートキャンプのプラクティスでnpmを自作しました。
せっかくなのでqiitaで公開させてもらおうと思ったので、勇気を出して書かせてもらってます。
「もっとこうした方がいいんじゃない?」などのご意見がありましたらコメントしてもらえると嬉しいです!
どんなnpmを作ったのか
作ったnpmは、最近流行りのトレーニング手法であるHIIT(High Intensity Interval Training)のタイマーです。
話題の筋トレ「HIIT」とは?
HIITとは、「High Intensity Interval Training(高強度インターバルトレーニング)」の略で、負荷の高い運動と小休憩を繰り返すトレーニング法のこと。限界まで体を追い込むことで、常に脂肪が燃焼しやすい状態をキープし、体脂肪減少と筋肉増量効果を得るものです。
実際に作成したnpmはこちらで確認できます↓
- npm:hiit_timer
- GitHub:github.com/R-Tsukada/hiit-timer
実際どんな感じで動くのか
ワークアウト時間の選択
インターバル時間の選択
1,2を何セット行うかを選択
作成したコード
最終的なコード
const log = require('single-line-log').stdout
const player = require('play-sound')(opts = {})
const { prompt } = require('enquirer')
const emoji = require('node-emoji');
async function hiitTimer(){
const workoutTimer = await prompt(
[
{
type: 'select',
name: 'workoutTime',
message: 'select workout time',
choices: ['10', '20', '30', '40', '50', '60']
},
{
type: 'select',
name: 'restTime',
message: 'select rest time',
choices: ['10', '20', '30', '40', '50', '60']
},
{
type: 'select',
name: 'set',
message: 'select set number?',
choices: ['1', '2', '3', '4', '5', '7', '8', '9', '10']
}
]
)
const workout = workoutTimer.workoutTime
const rest = workoutTimer.restTime
const set = workoutTimer.set
running(set, workout, rest)
}
async function running(setNumber, workout, rest){
await log('\x1b[32m10 seconds before Workout')
await firstWorkout(10)
for (let i = 0; i < setNumber; i++) {
log(emoji.get('fist') + ` Set${i + 1} Workoout Start ` + emoji.get('fist'))
await intervalTimer(workout)
log((emoji.get('relaxed')) + ` Set${i + 1} Break ` + (emoji.get('relaxed')))
await intervalTimer(rest)
}
await log((emoji.get('congratulations')) + ' Workout Finish' + (emoji.get('exclamation')) + 'Good Job' + (emoji.get('exclamation')) + (emoji.get('congratulations')))
}
function intervalTimer(selectWorkout) {
return new Promise(resolve => {
setTimeout(() => {
const startEffect = player.play('start_effect.mp3')
resolve()
}, selectWorkout * 1000)
}
)
}
function firstWorkout(second) {
return new Promise(resolve => {
setTimeout(() => {
const startEffect = player.play('start_effect.mp3')
resolve()
}, second * 1000)
})
}
hiitTimer()
悩んだ点
今回色々悩んだことが、「ワークアウトとインターバルを設定したセット数を繰り返す」ことでした。
繰り返すということはsetIntervalを使えばいいのでは?と考えて、↓のような考え方をしていました。
console.log('First Workuout Start')
const running = (function(){
console.log('First Workuout Start')
let number = 1
setInterval(function() {
if (number === 2) {
console.log('break')
} else if (number === 3) {
console.log('Workuout Start')
}
number += 1
}, 1000)
})
async function play(hiitNumber){
for (let i = 0; i < hiitNumber; i++) {
running()
}}
play(1)
このコードでも一応実装したい通りの動きになったのですが、、
First Workuout Start
break
Workuout Start
play(3)のようにセット数を複数回繰り返すと、
First Workuout Start
break
break
break
Workuout Start
Workuout Start
Workuout Start
break、Workuout Startが連続で処理されてしまってインターバルのタイマーになりませんでした。
非同期的に処理されてしまってるので、同期処理になるようにコードを変える必要性があるなと思いました。
修正した点
非同期処理が原因でインターバルタイマーの動きになってないので、同期処理になるようにコードを修正。
そもそもsetIntervalが非同期処理を前提にしたメソッドなので、setIntervalではなく、setTimeoutを繰り返し処理を使うことにしました。
intervalTimerというメソッドを作成して、workout(運動時間)、rest(休憩時間)の時間をそれぞれ引数で渡します。
まずはenquireを使ってworkout, rest, set(セット数)を決めます。
sync function hiitTimer(){
/* enquireで,workout、rest、setを選択 */
const workoutTimer = await prompt(
[
{
type: 'select',
name: 'workoutTime',
message: 'select workout time',
choices: ['10', '20', '30', '40', '50', '60']
},
{
type: 'select',
name: 'restTime',
message: 'select rest time',
choices: ['10', '20', '30', '40', '50', '60']
},
{
type: 'select',
name: 'set',
message: 'select set number?',
choices: ['1', '2', '3', '4', '5', '7', '8', '9', '10']
}
]
)
const workout = workoutTimer.workoutTime
const rest = workoutTimer.restTime
const set = workoutTimer.set
running(set, workout, rest)
}
enquireで選択したworkout, restをsetTimeout に渡す。
function intervalTimer(selectWorkout) {
return new Promise(resolve => {
setTimeout(() => {
const startEffect = player.play('start_effect.mp3')
resolve()
}, selectWorkout * 1000)
}
)
}
async/await を使って同期処理で実行。
async function running(setNumber, workout, rest){
await log('\x1b[32m10 seconds before Workout')
await firstWorkout(10)
for (let i = 0; i < setNumber; i++) {
log(emoji.get('fist') + ` Set${i + 1} Workoout Start ` + emoji.get('fist'))
await intervalTimer(workout)
log((emoji.get('relaxed')) + ` Set${i + 1} Break ` + (emoji.get('relaxed')))
await intervalTimer(rest)
}
await log((emoji.get('congratulations')) + ' Workout Finish' + (emoji.get('exclamation')) + 'Good Job' + (emoji.get('exclamation')) + (emoji.get('congratulations')))
}
これでHIITのタイマー機能を実装することができました!
改善したい点
最後に改善したい点について書きます。
アドバイス等がありましたらコメントをいただけると嬉しいです!
node_modules/hiit_timerのディレクトリに移動しなければ使えない
作成したnpmはmp3を使用しているので、mp3が入ってるnode_modules/hiit_timerに移動しないと使えないです。。
リファクタリングが不十分
もう少しスッキリしたコードになるんじゃないかと思うのですが、具体的にどうしたらいいのかわからず。。
↧