在承诺内部的派遣行动然后在佐贺的功能
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在承诺内部的派遣行动然后在佐贺的功能相关的知识,希望对你有一定的参考价值。
我有一个传奇(使用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');
}
}
答案
一个传奇'收益率调用'将等待返回的承诺完成。如果它失败了,它会抛出一个错误,所以不要使用'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);
}
}
以上是关于在承诺内部的派遣行动然后在佐贺的功能的主要内容,如果未能解决你的问题,请参考以下文章