BETA

redux-sagaでeventChannelを使ってputする

投稿日:2020-02-28
最終更新:2020-02-28

はじめに

redux-sagaでactionをdispatchする際、通常は

yield put(...)  

と書く。しかし、これができないときがある。例えばtensorflow.jsのmodelのfitを行うとする。このとき、バッチごとにlossとaccをdispatchしたいとする。そこで

await model.fit(trainData.xs, trainData.labels, {  
    batchSize,  
    validationSpilit,  
    epochs: trainEpochs,  
    callbacks: {  
        onBatchEnd: async(batch, logs) => {  
            // ここでlogs.lossとlogs.acc(をセットするaction)をdispatchしたい!  
        }  
    }  
})  

上のような状況になってしまう。こういうときにどうすればよいか。payloadでdispatchを引き回すのも手かもしれないが、webworkerで上をやると、メインスレッドから関数であるdispatchを取ってこれない。そういうときにeventChannelが使える。

eventChannel

function* setLossAndAccChannel(lossAndAcc) {  
  const chan = eventChannel(emitter => {  
    lossAndAcc.on('logs', (logs) => emitter(logs))  
    return () => {}  
  })  
  while(true) {  
    const {loss, acc} = yield take(chan)  
    // ここでlossとacc(をセットするactionを)dispatchする  
    yield all([  
      put(setLoss(loss)),  
      put(setAcc(acc))  
    ])  
  }  
}  

として、

// emitterはEventEmitter  
yield fork (setLossAndAccChannel, emitter)  

としておく。後はmodel.fitのcallbackで

    callbacks: {  
        onBatchEnd: async(batch, logs) => {  
            emitter.emit('logs', logs)  
        }  

とやれば、バッチごとにlossとacc(をセットするaction)がdispatchされる。

技術ブログをはじめよう Qrunch(クランチ)は、プログラマの技術アプトプットに特化したブログサービスです
駆け出しエンジニアからエキスパートまで全ての方々のアウトプットを歓迎しております!
or 外部アカウントで 登録 / ログイン する
クランチについてもっと詳しく

この記事が掲載されているブログ

@Catminusminusの技術ブログ Frontend/Machine Learning/C++など、興味のあるものについて、小ネタや調査中のこと、備忘録を書いたりします

よく一緒に読まれる記事

0件のコメント

ブログ開設 or ログイン してコメントを送ってみよう