Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/462.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 未能按预期执行的复杂异步流_Javascript_Reactjs_Asynchronous_Promise_Async Await - Fatal编程技术网

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

Javascript 未能按预期执行的复杂异步流,javascript,reactjs,asynchronous,promise,async-await,Javascript,Reactjs,Asynchronous,Promise,Async Await,我已经试了好几个小时了,但还是没有得到正确的流程。我将先分享代码,稍后再解释 jobSearch(); const jobSearch = () => { return (dispatch) => { console.log('DEBUG::step 1:'); if (!refreshToken()) { console.log('DEBUG::step 6:'); //....... //Call function to print

我已经试了好几个小时了,但还是没有得到正确的流程。我将先分享代码,稍后再解释

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

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;
  }
};
然后流更改为getting exception,如下所示:

调试::步骤1:

调试::步骤2:

调试::步骤3:

调试::步骤4:

调试::HI0:

调试::步骤6:

调试::hihi1:

因此,由于它被标记为async,它将始终返回一个承诺,这总是导致一个真实的值

因为它是异步的,所以您应该遵守承诺响应并对其进行评估:

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语句中使用了一个承诺,这总是会导致if语句跳过。

refreshToken是异步的,因此您在一开始就忘记了等待refreshToken。或者调用。然后在它上检查其值。refreshToken,返回一个承诺,将始终truthy@CertainPerformance当前位置我刚刚根据您所说的内容进行了更新,但现在日志的打印方式有所不同。从步骤1到hihi0,但不是步骤7,而是打印步骤6,hihi1@Isaac第8步和第9步在哪里?@briosheje,很抱歉遗漏了这一点,因为这并不重要,我已经从我的评论中删除了。并增加了问题,如果无论如何相关,但我怀疑索克斯。。。有一个自己的流,它不是主流的一部分。在操作前粘贴等待。尝试无效。你可以尝试返回斧头。后。。。但这项操作的成功与否取决于.trunt返回的操作,我不知道。我已更新了我的问题并尝试了您的解决方案,但在tooconsole.log'DEBUG::hihi3:'中失败;只有在网络请求失败时才会打印,所以我没有预料到。放在那里只是为了表明我们的请求没有失败
if (!refreshToken()) {
     ^------ this is async.. Which returns a Promise<boolean>, which is always truthy.
const refreshToken = async () // and some other stuff.
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
}