首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >未能按预期执行的复杂异步流

未能按预期执行的复杂异步流
EN

Stack Overflow用户
提问于 2018-08-25 04:33:53
回答 1查看 61关注 0票数 0

我已经试了好几个小时了,但没能得到正确的流量。我将先分享代码,然后再解释。

代码语言:javascript
复制
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检索新令牌,因此上面有一个网络请求,函数refreshToken将返回一个布尔值,以指示整个刷新令牌流是否成功或失败。

代码语言:javascript
复制
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: 调试::hi0: 调试::步骤7: 调试::hihi1 1:

  • 为什么Step 7打印在hihi1之前?我已经把它做成async await了。
  • 没有打印step 6,因此refreshToken操作成功
  • hihi3没有打印,所以也不例外

任何帮助都是非常感谢的!

更新!

正如@CertainPerformance和@briosheje所评论的:我已经更新到下面:

代码语言:javascript
复制
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: 调试::hi0: 调试::步骤6: 调试::hihi1 1:

EN

回答 1

Stack Overflow用户

发布于 2018-08-25 04:51:11

代码语言:javascript
复制
if (!refreshToken()) {
     ^------ this is async.. Which returns a Promise<boolean>, which is always truthy.

(如上文所述):

代码语言:javascript
复制
const refreshToken = async () // and some other stuff.

因此,由于它被标记为async,所以它总是返回一个Promise,这总是导致一个真实的值。

由于它是异步的,所以您应该保留承诺响应,并对其进行评估:

代码语言:javascript
复制
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语句跳过。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52014068

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档