Можно ли вызвать асинхронную функцию внутри конструктора в Reaction-native? - PullRequest
5 голосов
/ 06 марта 2019

У меня есть асинхронная функция с именем async a(), которую нужно запустить перед функцией componentDidMount().

Так как я могу вызвать асинхронную функцию внутри конструктора?Поскольку функция конструктора запускается до функции componentDidMount.

Я должен быть уверен, что мой async a() сначала завершается в конструкторе, а затем выполняются все методы в componentDidMount.

Ответы [ 6 ]

7 голосов
/ 06 марта 2019

Асинхронный конструктор является потенциальным антипаттерном, поскольку он не приводит к ожидаемому от него поведению.

Асинхронные побочные эффекты должны возникать после монтирования компонента и, таким образом, возникают в componentDidMount, этоэто то, для чегоНевозможно отложить жизненный цикл компонента и неправильно думать об этом в следующих терминах.

Он должен работать так:

class Foo extends Component
  async a() {...}

  async componentDidMount() {
    await this.a();
  }

  render() {
    (conditionThatIsTrueWhenThereResult) ? (
      <div>...the result from a...</div>
    ) : (
      <div>fallback</div>
    );
  }
}

Если необходимо поддерживать компонент синхронным,a Асинхронный побочный эффект должен быть перенесен в родительский компонент, который отображает дочерний элемент только тогда, когда результат из a готов к использованию.

4 голосов
/ 06 марта 2019

Вы не можете сделать это внутри конструктора, потому что конструктор не может использовать await
Таким образом, вы можете иметь другую функцию (например, b()) для всех процессов, которые вы хотите запустить после async a().И у вас есть два варианта сделать это:

1 - использовать async/await:

async componentDidMount() {  
    await a();  // it will wait here untill function a finishes

    b(); // after function a finished, this function will calls
}

2 - используя .then:

componentDidMount() {
    // in below line, function `a` will call, and when it finishes, the function inside `.then` will be notified
    a().then(() => {
        b(); // now your function `a` finished completely and you can call extra process in function `b`
    });
}
1 голос
/ 06 марта 2019

Асинхронная работа в конструкторе - нет, нет.

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

Другое решение состоит в том, чтобы довести эту логику до тех, кто рендерит этот компонент. Родитель должен инициировать асинхронный вызов и визуализировать компонент только после асинхронного вызова.


Как и предполагали другие, вы можете использовать componentDidMount из жизненного цикла компонента, чтобы справиться с этим.
Смотри: https://reactjs.org/docs/state-and-lifecycle.html

1 голос
/ 06 марта 2019

Вызов a() в componentDidMount, например, так:

async componentDidMount() {
       await a();
       otherFuncions()
}

otherFunctions() будет выполняться только после завершения a()

0 голосов
/ 06 марта 2019

Привет всем, кто я тестировал весь код, на который вы ответили, но результат все равно ниже

async function a() {
    setTimeout(() => {
        console.log('A');
    }, 2000);
}

async function b() {
    setTimeout(() => {
        console.log('B')
    }, 1000);
}

function c() {
    console.log("C");
}


async function componentDidMount() {
    await a();
    await b();
    c();
}

componentDidMount();

Выход: C В A

Как вы сказали здесь, A и B должны заканчиваться сначала, затем последней не асинхронной функцией. A

0 голосов
/ 06 марта 2019

используйте UNSAFE_componentWillMount() или componentWillMount() или лучше прочитайте это https://reactjs.org/docs/react-component.html#unsafe_componentwillmount или, пожалуйста, найдите что такое конструктор.

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