【问题标题】:Complex async flow that failed to execute as expected未能按预期执行的复杂异步流
【发布时间】:2018-08-25 13:00:39
【问题描述】:

我已经尝试了几个小时,但无法获得正确的流程。我先分享代码,后面再解释。

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会返回一个指示整个刷新令牌流是成功还是失败的布尔值。

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;
  }
};

下面是打印出来的日志

调试::步骤 1:

调试::步骤 2:

调试::步骤 3:

调试::步骤 4:

调试::hihi0:

调试::步骤 7:

调试::hihi1:

  • 为什么Step 7 打印在hihi1 之前?我已经成功了async await

  • step 6 没有打印,所以 refreshToken 操作成功

  • hihi3 没有被打印出来,所以也不例外

任何帮助将不胜感激!

更新!

正如@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
  }
}

然后流程变为如下异常:

调试::步骤 1:

调试::步骤 2:

调试::步骤 3:

调试::步骤 4:

调试::hihi0:

调试::步骤 6:

调试::hihi1:

【问题讨论】:

  • refreshTokenasync,所以一开始你忘了await refreshToken()。 (或在其上调用 .then 以检查其值。refreshToken(),返回 Promise,将始终真实)
  • @CertainPerformance:我刚刚根据你所说的更新了它,但现在打印的日志不同了。从step1hihi0,但不是step7,而是打印step 6hihi1
  • @Isaac 第 8 步和第 9 步在哪里?
  • @briosheje,很抱歉错过了这一点,因为这并不重要,我已从我的评论中删除。并提出疑问,如果这无论如何相关,但我对此表示怀疑
  • ax.post()... 有自己的流程,它不是主要流程的一部分。在operation.attempt() 前面粘贴await 无效。您可以尝试return ax.post()...,但其成功取决于operation.attempt() 返回的内容,我不知道。

标签: javascript reactjs asynchronous promise async-await


【解决方案1】:
if (!refreshToken()) {
     ^------ this is async.. Which returns a Promise<boolean>, which is always truthy.

(如此处所述):

const refreshToken = async () // and some other stuff.

因此,由于它被标记为async,它总是会返回一个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 语句跳过。

【讨论】:

  • 我已经更新了我的问题并尝试了您的解决方案,但也失败了
  • console.log('DEBUG::hihi3:'); 只会在网络请求失败时打印,所以我没想到。放在那里只是为了表明我们的请求没有失败
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-15
  • 2019-04-09
  • 1970-01-01
  • 2018-12-02
相关资源
最近更新 更多