在承诺内部的派遣行动然后在佐贺的功能

问题描述 投票:1回答:1

我有一个传奇(使用redux-saga)调用一个POST到API端点的函数(使用axios)。通过axios进行更深入的API调用会返回一个承诺。我想在承诺的then()方法内部发送动作,但我显然不能使用yield。一个put()似乎没有任何东西。这样做的正确方法是什么?

这是传奇:

export function* loginFlow(action) {
  try {
    const {username, password} = action.payload;
    const responsePromise = yield call(login, {username, password, isRegistering: false});
    yield responsePromise
            .then(result => {
              console.log('loginFlow responsePromise result', result);
              put(creators.queueLoginSucceededAction()); // doesn't work
              put(push('/')); // doesn't work
            })
            .catch(err => {
              console.log('loginFlow responsePromise err', err);
              put(creators.queueLoginFailedAction()); // doesn't work
            });
  }
  catch(err) {
    console.log(err);
    yield put(creators.queueLoginFailedAction());
  }
}

这是被调用的函数:

export function* login(options) {
  try {
    // if we are already logged in, via token in local storage,
    // then skip checking against server
    if( store.get('token') ) {
      return Promise.resolve('Already logged in.');
    }

    // query server for valid login, returns a JWT token to store
    const hash = yield bcrypt.hashSync(options.password, 10);
    yield put(creators.queueLoginHttpPostedAction());
    return axios.post('/auth/local', {
              params: {
                username: options.username,
                password: hash,
                hash:     true,
              }
            })
            .then(result => {
              console.log('api>auth>login>result', result);
              put(creators.queueLoginHttpSucceededAction()); // doesn't work
              return Promise.resolve('Login successful');
            })
            .catch(err => {
              console.log('api>auth>login>err', err);
              put(creators.queueLoginHttpFailedAction()); // doesn't work
              return Promise.reject(err.message);
            });
  }
  catch (err) {
    yield put(creators.queueLoginHttpFailedAction());
    return Promise.reject('Login could not execute');
  }
}
redux promise react-redux redux-saga
1个回答
1
投票

一个传奇'收益率调用'将等待返回的承诺完成。如果它失败了,它会抛出一个错误,所以不要使用'then'和'catch'代替promises,你可以使用普通的try-catch代替。

Redux Saga文档更详细地解释了这一点 - 绝对值得一读:

https://redux-saga.js.org/docs/basics/ErrorHandling.html

换句话说,下面的login(options)函数将执行HTTP请求,只要它不发回被拒绝的promise,它就会继续对成功的操作进行排队并将用户重定向回来。如果它确实发回了被拒绝的承诺,它将立即跳转到'catch'块。

更正了登录流程:

export function * loginFlow(action) {
  try {
    const {username, password} = action.payload;
    const responsePromise = yield call(login, {username, password, isRegistering: false});
    console.log('loginFlow responsePromise result', result);
    yield put(creators.queueLoginSucceededAction());
    yield put(push('/'));
  }
  catch(err) {
    console.log('loginFlow responsePromise err', err);
    yield put(creators.queueLoginFailedAction());
  }
}

而对于实际的登录过程:

export function * login(options) {
  // if we are already logged in, via token in local storage,
  // then skip checking against server
  if( store.get('token') ) {
    return Promise.resolve('Already logged in.');
  }

  // query server for valid login, returns a JWT token to store
  const hash = yield bcrypt.hashSync(options.password, 10);
  yield put(creators.queueLoginHttpPostedAction());

  try {
    yield call(
      axios.post, 
      '/auth/local', 
      { params: { username: options.username, password: hash, hash: true } }
    )

    console.log('api>auth>login>result', result);
    yield put(creators.queueLoginHttpSucceededAction()); // doesn't work
    return Promise.resolve('Login successful');

  } catch(err) {
    console.log('api>auth>login>err', err);
    yield put(creators.queueLoginHttpFailedAction()); // doesn't work
    return Promise.reject(err.message);
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.