Сложный асинхронный поток, который не удалось выполнить должным образом - PullRequest
0 голосов
/ 25 августа 2018

Я пытался часами, но не смог получить правильный поток. Сначала я поделюсь кодом, а объяснение придет позже.

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

А ниже распечатанный журнал

ОТЛАДКА :: шаг 1:

ОТЛАДКА :: шаг 2:

ОТЛАДКА :: шаг 3:

ОТЛАДКА :: шаг 4:

DEBUG :: hihi0:

ОТЛАДКА :: шаг 7:

DEBUG :: 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:

DEBUG :: шаг 3:

ОТЛАДКА :: шаг 4:

DEBUG :: hihi0:

DEBUG :: шаг 6:

DEBUG :: hihi1:

1 Ответ

0 голосов
/ 25 августа 2018
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 или что бы это ни было.В любом случае главная проблема заключается в том, что вы использовали Promise внутри оператора if, что всегда приводило к пропуску оператора if.

...