我已经尝试了几个小时但无法获得正确的流程。我先分享代码,稍后再解释。
jobSearch();
const jobSearch = () => {
return (dispatch) => {
console.log('DEBUG::step 1:');
if (!refreshToken()) {
console.log('DEBUG::step 6:');
//.......
//Call function to print step 8, step 9
} else {
console.log('DEBUG::step 7:');
//Perform other operation
}
}
基本上,refreshToken()
是一个方法,它是解码jwt以检查是否过期,如果过期,则调用REST检索新的 token ,因此上面有一个网络请求,并且函数refreshToken
将返回一个 bool 值来指示整个刷新 token 流程是成功还是失败。
const refreshToken = async () => {
console.log('DEBUG::step 2:');
let valid = true;
if (!validateAccessToken()) { //<==just a flow to decode jwt, no async flow
console.log('DEBUG::step 4:');
// Configure retry operation
const operation = retry.operation({
retries: MAX_RETRIES_USER_LOGIN,
factor: 1,
minTimeout: INTERVAL_RETRY_USER_LOGIN,
maxTimeout: INTERVAL_RETRY_USER_LOGIN
});
// Configure HTTP request
const ax = axios.create({
timeout: TIMEOUT_CONNECT,
headers: {
'Content-Type': 'application/json; charset=utf-8'
},
cancelToken: cancelTokenSourceJobSearch.token
});
console.log('DEBUG::hihi0:');
await operation.attempt(() => {
ax.post(urljoin(API_BASE_URL, API_ENDPOINT_TOKEN_REFRESH), {
data: {
refresh_token: global.setting.refresh_token
}
})
.then(({ data }) => {
valid = true;
console.log('DEBUG::hihi1:');
//SUCCESS!
}).catch((err) => {
console.log('DEBUG::hihi3:');
// Log error to console
console.log(err);
if (axios.isCancel(err)) {
valid = false;
return;
} else if (operation.retry(err)) {
valid = false;
return;
}
});
return valid;
});
} else {
console.log('DEBUG::step 5:');
return valid;
}
};
下面是打印的日志
DEBUG::step 1:
DEBUG::step 2:
DEBUG::step 3:
DEBUG::step 4:
DEBUG::hihi0:
DEBUG::step 7:
DEBUG::hihi1:
为什么
Step 7
在hihi1
之前打印?我已经将其设置为async wait
。第6步
未打印,因此refreshToken操作成功hihi3
未打印,因此也不异常(exception)
任何帮助将不胜感激!
更新!
正如 @CertainPerformance 和 @briosheje 所评论的:我已更新为以下内容:
jobSearch();
const jobSearch = () => {
return async (dispatch) => { //<==HERE
console.log('DEBUG::step 1:');
const shouldRefreshToken = await refreshToken();//<==HERE
if (!shouldRefreshToken) {//<===HERE
console.log('DEBUG::step 6:');
//.......
//Call function to print step 8, step 9
} else {
console.log('DEBUG::step 7:');
//Perform other operation
}
}
然后流程变为出现异常,如下所示:
DEBUG::step 1:
DEBUG::step 2:
DEBUG::step 3:
DEBUG::step 4:
DEBUG::hihi0:
DEBUG::step 6:
DEBUG::hihi1:
最佳答案
if (!refreshToken()) {
^------ this is async.. Which returns a Promise<boolean>, which is always truthy.
(如此处所述):
const refreshToken = async () // and some other stuff.
因此,由于它被标记为async
,因此它将始终返回一个Promise
,这始终会导致一个真值。
由于它是异步的,您应该保留 promise 响应并对其进行评估:
console.log('DEBUG::step 1:');
// Store here the value of refreshToken
const shouldRefreshToken = await refreshToken();
if (!shouldRefreshToken) {
// ^--- Syncronous flow here.
console.log('DEBUG::step 6:');
//.......
} else {
console.log('DEBUG::step 7:');
//Perform other operation
}
除此之外,refreshToken
方法内的顺序取决于您在其中使用的方法。如果由于某种原因,您期望调用 console.log('DEBUG::hihi3:');
,请检查 axios 文档或其他内容。
无论如何,主要问题是您在 if 语句中使用了 Promise,这总是会导致 if 语句跳过。
关于javascript - 复杂的异步流程未能按预期执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52014068/