0

loginSagaを取得するための API 呼び出しを実行するサガがありaccessTokenます。これが成功したら、これでそのダウンロードデータをスピンアップするために他のサガをたくさん持ってみたいと思いますaccessToken

これらのサガは に依存しているaccessTokenため、 が表示されるまで実行する必要がありLOGOUT_SUCCESSます。その後、終了する必要があります。彼らが現在何かをダウンロードしている場合、これはキャンセルされるべきであり、結果は無視されます。

これは私が今持っているものです:

function *authorize(credentials) {
  try {
    const { email, password, device_name, device_family, device_token } = credentials
    const { access_token, user } = yield call(api.loginAsync, email, password, { device_name, device_family, device_token })
    yield put(actions.loginSuccess(access_token, user))
  } catch(error) {
    console.error(error)
    if (!isCancelError(error)) {
      if (error.response && error.response.status == 401) {
        error.message = "E-Mail or Password wrong"
      }
      yield put(actions.loginError(error))
    }
  }
}

function *loginFlow() {
  while(true) {
    console.info("Waiting for account/LOGIN")
    const credentials = yield take(actions.LOGIN)
    const authorizeTask = yield fork(authorize, credentials)

    console.info("Waiting for account/LOGOUT")
    const { type } = yield take([actions.LOGOUT, actions.LOGIN_ERROR])
    cancel(authorizeTask)
    if (type == actions.LOGOUT) {
      yield call(api.logoutAsync)
      yield put(actions.logoutSuccess())
    }
  }
}

次に、LOGIN_SUCESS依存するサガ:

function *refreshUser() {
  while (true) {
    const result = yield take([actions.LOGIN_SUCCESS, actions.REFRESH_USER])
    try {
      const user = yield call(api.getUserAsync)
      yield put(actions.userRefreshed(user))
    } catch (error) {
    }
  }
}


function *getActivities(access_token) {
  console.info("fetch activities")
  try {
    const activities = yield call(api.getActivitiesAsync, access_token)
    console.info("activities fetched")
    yield put(activitiesUpdated(activities))
  } catch (error) {
  }
}

function *updateActivities() {
  while (true) {
    const { access_token } = yield take(actions.LOGIN_SUCCESS)
    console.info("Calling getActivities")
    yield call(getActivities, access_token)
    while (true) {
      const {type } = yield take([actions.REFRESH_ACTIVITIES, actions.LOGOUT])
      if (type == actions.LOGOUT) {
        break
      }
      yield call(getActivities, access_token)
    }
  }
}

そして、それらはすべて を必要とするため、ペイロードでそれを運ぶため、accessTokenまで待たなければなりません。LOGIN_FINISHED

また、私の冒険談はすべて最初から開始され、待機しています。

authorizeフローが終了するloginDependingSagasと、をパラメーターとしてスピンアップできるのではないかと思いaccessTokenました。

そのようです:

関数 forkLoginDependingSagas(accessToken) { fork refreshUser(accessToken) fork updateActivities(accessToken) }

それは良いパターンですか?

4

1 に答える 1

0

この問題は、 を運ぶアクションを待機し、access_tokenthis に応じてサガをフォークする別のサガを使用して解決しましたaccess_token

function* authorizedFlow() {
  let payload
  while (({ payload } = yield take([actions.LOGIN_SUCCESS, actions.START_SIGNUP_SUCCESS]))) {
    const { access_token } = payload
    yield fork(logoutFlow, access_token)
    yield race({
      watchers: [
        call(refreshUser, access_token),
        call(refreshInvoices, access_token),
        call(refreshPendingTransactions, access_token),
      ],
      logout: take(actions.LOGOUT_SUCCESS),
    })
  }
}

function* logoutFlow(access_token) {
  while (yield take(actions.LOGOUT)) {
    try {
      yield call(api.logoutAsync, access_token)
      yield put(actions.logoutSuccess())
    } catch (error) {
      yield put(actions.logoutError(error))
    }
  }
}

logoutFlow は、ログアウトが成功した場合に、依存するサガのrace間でそれらのサガがキャンセルされることを保証します。access_token

于 2016-08-29T23:24:48.913 に答える