React Native - запускать функции синхронно - PullRequest
0 голосов
/ 29 ноября 2018

Я написал следующий код, он работает гладко , но я столкнулся с вопросом:

submitFormToBackend = async () => {
  if (this.paymentMethod === 'apple-pay') {
    this.setState({ showLoadingIndicator: true }); // <-- below await setTimeout can confirm this line run before it
  }

  let requester = new ApplePayRequester({...this.form});
  let applePay = new ApplePay();

  await setTimeout(async () => {
    let cardTokenResponse = await applePay.getCardToken();
    if (cardTokenResponse.isSuccess()) {
      requester.setCardToken(cardTokenResponse.message);
      let response = await requester.pushToBackend();

      this.setState({ showLoadingIndicator: false }); //<-- below setTimeout can confirm this line run before them
      if (response.isSuccess()) {
        setTimeout(() => { this.navigator.backToPreviousScreen(); }, 800);
      } else {
        setTimeout(() => { Alert.alert('your purchase has error. Try again'); }, 800);
      }
    } else {
      this.setState({ showLoadingIndicator: false });
      setTimeout(() => { Alert.alert('cannot get your card token.'); }, 800);
    }
  }, 800);
};

Мой render () в этом компоненте:

render() {
  return (
    <View style={styles.form}>
      <LoadingIndicator visible={this.state.showLoadingShader} />

      <InputBox />
      <InputBox />

      <SubmitButton />
    </View>
  );
}

Как вы видите, существует множество setTimeout() функций, похоже, что функции будут аварийно завершаться, если я не использую setTimeout() для ограничения функций, запускаемых одна за другой.

Однако это не очень хорошая практика, так как для успешного выполнения миллисекунды по умолчанию нет (миллисекунда может быть установлена ​​в 700 мс, 1500 мс или т. Д.).Поэтому я хотел бы спросить, есть ли какое-либо решение, подтверждающее, что предыдущая функция была запущена до следующего запуска функции, кроме использования setTimeout()?

Благодарю за чью-либо помощь.


ОБНОВЛЕНИЕ

enter image description here

Процедуры:

Шаг 1 - Нажмите кнопку подтверждения
Шаг 2 - Вызвать модальное подтверждение
Шаг 3 - Подтвердить, отменить модальное подтверждение, установить showLoadingIndicator на true, чтобы показать индикатор загрузки
Шаг 4 - вызов ApplePay и всплывающий пользовательский интерфейс ApplePay
Шаг 5 - Подтверждение пользователя, установите showLoadingIndicator в false, чтобы отключить индикатор загрузки и перейти на предыдущий экран


Проблемы, возникающие при отсутствии setTimeout():

Шаг 4 - интерфейс ApplePay не может появиться после установки showLoadingIndicator в true, нижекод, с которым возникла проблема:

 let cardTokenResponse = await applePay.getCardToken();

Шаг 5 - предупреждение будет всплывать перед установкой showLoadingIndicator на false, что останавливаетПри настройке ниже приведен код, с которым возникла проблема:

  this.setState({ showLoadingIndicator: false });
  if (response.isSuccess()) {
  } else {
    setTimeout(() => { Alert.alert('your purchase has error. Try again'); }, 800);
  }

1 Ответ

0 голосов
/ 29 ноября 2018

Второй необязательный параметр функции setState - это функция обратного вызова, которая запускается синхронно с изменением состояния.

Так что вы можете просто положиться на следующее:

this.setState({
  //change state variables here
}, () => {
   //do the next work here...
});

Обратный вызовФункция всегда запускается после изменения состояния.

В вашем коде это будет работать:

this.setState({ showLoadingIndicator: false }, () => {
  if (response.isSuccess()) {
      this.navigator.backToPreviousScreen();
  } else {
   Alert.alert('your purchase has error. Try again');
  }
});

Надеюсь, это поможет вам.Удачного кодирования:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...