Область js выполняет запрос асинхронно - PullRequest
0 голосов
/ 25 апреля 2018

Я использую React-Native с Realm Database.
Я попытался выполнить запросы на чтение, используя шаблон async / await , но похоже, что он всегда выполняется синхронно, замораживая пользовательский интерфейс, поскольку запрос занимает не менее пары секунд до визуализации (из-за возможного большого объема сохраненных данных).

Это код, который я использую (это копирование и вставка, но чтобы дать вам представление), я что-то упустил?

export default class CustomComponent extends React.Component {
 constructor(props) {
   super(props);
   this.state = {
     value:0
   };
   this.realm = this.buildRealm();
 }

  buildRealm() {
        return new Realm({ schema: [EventSchema] });
 }

  componentWillMount() {
    this.fetchData().then(result => { this.setState(value:result);});
  }

  async fetchData() {    
    var appState = await someMethod()
    return appState;
  }

  someMethod() {
   return new Promise(resolve => {
         resolve(queryFromDB())
        });
  }

  queryFromDB() {
     // Returns a value fetched from Realm
     let events = this.realm.objects("Event");
     return events.length;
   }

  render() {
   return (
     <Text> {this.state.value} </Text> 
   );
  }
}

Ответы [ 3 ]

0 голосов
/ 14 сентября 2018

Запрос области является синхронным, нет возможности сделать его асинхронным.Похоже, что вы используете область с React Native, в этом случае лучшее решение - отложить запрос области, используя менеджер взаимодействия

async componentDidMount() {
  // loading objects from realm is a synchronous task that block the main
  // process, in order not to freeze the ui, we trigger the load after
  // the interactions and screen loading is done
  this.getRealmDataHandle = InteractionManager.runAfterInteractions(() => this.getRealmData())
}

componentWillUnmount() {
  if (this.getRealmDataHandle !== undefined) {
    this.getRealmDataHandle.cancel()
  }
}

Сначала смонтируйте и отрендерите компонентэкран загрузки, затем, когда поток рендеринга пользовательского интерфейса завершит свою работу, диспетчер взаимодействия вызовет запрос области.Таким образом, пользователь не испытывает слишком много зависаний пользовательского интерфейса.

Я надеюсь, что однажды команда realmJS предоставит асинхронную версию, но я сомневаюсь, что это скоро произойдет.

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

Я решил это с setTimeout на некоторое время. Например:

componentDidMount() {
    setTimeout(this.fetchData.bind(this), 0);
}

fetchData(){
   let events = this.realm.objects("Event");
   this.setState({
       value: events,
   });
}
0 голосов
/ 25 апреля 2018

Вы пытались получить данные на componentDidMount вместо willMount?

WillMount требует, чтобы ваши функции завершились до начала монтажа.

Затем можно добавить состояние пользовательского интерфейса загрузки (счетчик, образец текста и т. Д.).

Затем, возможно, выполнитеваш state.value по умолчанию, который вы обновляете после завершения запроса.

...