2

ユーザーがログインするたびに「お気に入り」をロードするアプリがあります。データは、localforage を使用して IndexedDB からロードされます。アプリが新しく起動したとき(ウィンドウの更新後)に完全に機能します。ログアウトしてログインすると (ルート saga タスクの実行中)、「お気に入り」データをロードする呼び出しでエラーがスローされます。

TypeError: null のプロパティ 'ready' を読み取れません

ステップで:

export function* handleRecoverFavorites() {
  try {
    const resp = yield call(localforage.getItem, 'favorites')

サガコードの抜粋:

export function* handleRecoverFavorites() {
  try {
    const resp = yield call(localforage.getItem, 'favorites')
    if(resp) {
      yield put(recoverFavorites(resp))
      yield all(resp.map(symbol => put(getTickPricesSubscribe(symbol))));
          }
  } catch(err) {
    let response={"errorDescr":"Error whilst recovering favorites: "+err}
    yield put({ type: types.RESPONSE_ERR, response })
    console.log(response.errorDescr)
  }  
}


function* runAtStartupSubscirptions(socket, streamSessionId) {
  yield fork(send, {"command": "getBalance", "streamSessionId": streamSessionId }, socket );
  yield fork(handleRecoverFavorites)
  yield fork(handleRecoverCharts)
  while(true) {
    yield call(delay, STREAMING_PING_TIME)
    yield call(send, {"command": "ping", "streamSessionId": streamSessionId }, socket );
  } 
}

function* handleRequests(socket) {
  let streamSessionId = yield select(state => state.get("auth").get("streamSessionId"))

  while(true) {
    yield take(types.STREAMING_SOCKET_STATUS)
    if(socket.readyState === 1)
      yield fork(runAtStartupSubscirptions, socket, streamSessionId)
  }
}

export function* handleStreamingConnection() {
  let server = yield select(state => state.get("auth").get("server"))
  const socket = yield call(createWebSocketConnection, server+"Stream" )
  const socketChannel = yield call(createSocketChannel, socket, null)
  const task = yield fork(handleRequests, socket)

  let channelMsg;
  do {
    channelMsg = yield take(socketChannel)
    if(channelMsg.socketResponse) {
      const response = channelMsg.socketResponse;
      switch (response.command) {
        case "candle":
          yield put({ type: types.GET_CANDLES_STREAMING, response })
          break;

(...)

        default:
          console.log("unrequested data: "+response)
      }
    }
    if(channelMsg.socketStatus) {
      console.log(channelMsg)
      yield put({ type: types.STREAMING_SOCKET_STATUS, channelMsg })
    }  
  } while (channelMsg.socketStatus!=="Disconnected")
  yield cancel(task)
}

export default function* rootSaga() {
  while(true) {
    // Wait for log-in
    yield take(types.LOGIN_SUCCESS);
    const handleStreamingtask = yield fork(handleStreamingConnection)
    yield take([types.LOGOUT_REQUEST, types.RECONNECTING ])
    yield cancel(handleStreamingtask)
    const channelMsg={"socketStatus" : "Disconnected"}
    yield put({ type: types.STREAMING_SOCKET_STATUS, channelMsg })
  }
}

ご提案をいただければ幸いです。

saga 呼び出しなしで結果を確認するために、console.log 行を追加しました。

export function* handleRecoverFavorites() {
  try {
    console.log(localforage.getItem('favorites'))
    const resp = yield call(localforage.getItem, 'favorites')

Promise のたびに正しい値を返します。

Promise {<pending>}
__proto__:Promise
[[PromiseStatus]]:"resolved"
[[PromiseValue]]:Array(1)
0:"CHFPLN"
length:1
4

2 に答える 2

1

これは、「yield call」内で localforage メソッドを直接呼び出すのではなく、別のクラスにラップして解決した方法です。

export class LocalDataService {  
  getData = ( param ) => {
    return localforage.getItem(param)
      .then( result => result)
      .catch( reason => reason)
  }
}

export function* handleRecoverFavorites() {
  try {
    const api = new LocalDataService()
    const resp = yield call( api.getData, 'favorites')
(...)
于 2018-07-14T10:21:13.383 に答える