図から起してみました。こんなことです?
// 初期状態: valueは結果表示用、historyは履歴の記録用
const initState =
{value: undefined, history: []}
// メッセージ: 処理A、処理B、終了処理を定義:
const A = Symbol("A")
const B = Symbol("B")
const End = Symbol("End")
// 更新:
// 状態とメッセージをうけとって、状態を更新しつつ、結果を返す:
const innerAction = state => msg =>
( state =
msg === A ?
addToHist(state)(funcA())
: msg === B ?
addToHist(state)(funcB())
: msg === End ?
resetHist(state)
: noOp(state)
).value
// (初期状態を部分適用) メッセージを受け取って、状態を更新しつつ、結果を返す
const action = innerAction(initState)
// 状態と値をとって、新しい状態を返す:
const addToHist = state => value =>
({value: value, history: [...state.history, value] })
// 状態をとって、新しい状態を返す:
const resetHist = state =>
({value: state.history, history: [] })
const noOp = state =>
( {...state, value: undefined })
// 処理A、Bの関数の例:実行すると"何か"を返す:
const funcA = () => "resA"
const funcB = () => "resB"
// 使用例:
action(A) // 'resA'
action(B) // 'resB'
action(A) // 'resA'
action(End) // [ 'resA', 'resB', 'resA' ]
action(B) // 'resB'
action(End) // [ 'resB' ]
フロント側だけですけどね。これだけでもけっこういろんなことができるんじゃないかなあ。
クロージャを使って、指示に従って処理を実行しつつ状態を管理できます。
これは自前で 超適当に実装してますが、こんなことをお手軽かつ安全、大規模にやりたければ、The Elm Architecture (TEA)あたりで検索して、ピンときたフレームワーク/言語を使ってみるってのがいいと思います。
追記:
更新して表示する部分も含めて、もうちょっとまじめに codepen でやってみました。
See the Pen
rNWVrZo by ttatsf (@ttatsf)
on CodePen.
※ 素のJSで自前で状態管理の仕組みをやろうとしてるのでどうしても謎っぽいところが出てきます。参考程度にご覧ください。
さらに追記:
三目並べを作ってみました。
See the Pen
TicTacToe by ttatsf (@ttatsf)
on CodePen.
簡単ですが解説:
https://qiita.com/ttatsf/items/31d408893f33b2862007
本格的にやるには Elm/Vue/React/Svelteあたりでよさげだなと思うものに入門されるのがいいかと思います。