web-dev-qa-db-ja.com

反応ネイティブのコンストラクター内で非同期関数を呼び出すことは可能ですか?

関数async a()の前に実行する必要があるcomponentDidMount()という非同期関数があります。

では、コンストラクタ内で非同期関数を呼び出すにはどうすればよいですか?コンストラクタ関数は、componentDidMount関数の前に実行されるためです。

私のasync a()が最初にコンストラクタで完了し、次にcomponentDidMount内のすべてのメソッドが実行されることを確認する必要があります。

10
Iqbal Jan

コンストラクターはawaitを待機できないため、コンストラクター内では実行できません。
そのため、b()の後に実行するすべてのプロセスに対して、別の関数(たとえば、async a())を使用できます。これを行うには、2つの選択肢があります。

1- 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- .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`
    });
}
8
SiSa

非同期コンストラクターは、期待される動作を行わないため、潜在的なアンチパターンです。

非同期の副作用は、コンポーネントがマウントされた後に発生することが想定されているため、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非同期の副作用を移動する必要があります。

8
Estus Flask

次のように、componentDidMountでa()を呼び出します。

_async componentDidMount() {
       await a();
       otherFuncions()
}
_

otherFunctions()は、a()が完了した後にのみ実行されます

1
MPN7

コンストラクタでの非同期作業はノーノーです。

通常は、スピナーをレンダリングして非同期呼び出しをトリガーするコンポーネントを使用します。次に、非同期呼び出しが終了したら、このコンポーネントを更新して別のものをレンダリングできます。

別の解決策は、このロジックをこのコンポーネントをレンダリングしている誰にでもプッシュすることです。親は非同期呼び出しをトリガーし、非同期呼び出しの後でのみコンポーネントをレンダリングする必要があります。


他の人が示唆したように、コンポーネントのライフサイクルのcomponentDidMountを使用してこれを処理できます。
参照: https://reactjs.org/docs/state-and-lifecycle.html

1
tbraun

こんにちはすべてあなたが答えたすべてのコードをテストしましたが、それでも結果は以下のようになります

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 B A

ここで言ったように、AとBが最初に終了し、次に最後の非非同期関数が終了する必要があります。A

0
Iqbal Jan