简体   繁体   中英

Is it possible to call an async function inside a constructor in react-native?

I have an async function named async a() which has to be run before function componentDidMount() .

So how can I call an async function inside a constructor? Because the constructor function gets run before the componentDidMount function.

I need to be sure my async a() completes first in the constructor and then all methods within componentDidMount are executed.

You can't do it inside constructor, because constructor can't wait for await
So you can have another function(for example b() ) for all the processes you want to run after async a() . And you have two choice for doing this:

1- use async/await :

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

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

2- using .finally :

componentDidMount() {
    // in below line, function `a` will call, and when it finishes, the function inside `.finally` will be notified
    a().finally(() => {
        b(); // now your function `a` finished and you can call extra process in function `b`
    });
}

Asynchronous constructor is a potential antipattern because it doesn't result in behaviour that is expected from it.

Asynchronous side effects are supposed to happen after a component is mounted and thus occur in componentDidMount , this is what it's for. It's impossible to delay the lifecycle of a component and it's incorrect to think about it in these terms.

It's supposed to work like:

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

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

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

If it's necessary to keep a component synchronous, a asynchronous side effect should be moved to parent component that renders a child only when the result from a is ready to use.

Call a() in componentDidMount like so:

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

otherFunctions() will only be executed after a() is completed

Async work in constructor is a no no.

Typically you would either have a component that renders a spinner and triggers an async call. Then you can update this component to render something else once the async call is finished.

Another solution is to push that logic up to whoever is rendering this component. The parent should trigger the async call and render the component only after the async call.


As others suggested, you could use componentDidMount from the component lifecycle to handle this.
See: https://reactjs.org/docs/state-and-lifecycle.html

Hi every one I've test all code you have answered but still there the result is like below

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();

Output: CBA

As you said here A and B should be finish first then the last non async function. A

使用UNSAFE_componentWillMount()componentWillMount()或更好地阅读此https://reactjs.org/docs/react-component.html#unsafe_componentwillmount或请搜索什么是构造函数。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM