Dartのコンストラクタから非同期メソッドを呼び出す質問する

Dartのコンストラクタから非同期メソッドを呼び出す質問する

Dart で MyComponent を初期化するには、サーバーに HttpRequest を送信する必要があると仮定します。オブジェクトを同期的に構築し、応答が返されるまで「実際の」初期化を延期することは可能ですか?

以下の例では、「done」が出力されるまで _init() 関数は呼び出されません。これを修正することは可能ですか?

import 'dart:async';
import 'dart:io';

class MyComponent{
  MyComponent() {
    _init();
  }

  Future _init() async {
    print("init");
  }
}

void main() {
  var c = new MyComponent();
  sleep(const Duration(seconds: 1));
  print("done");
}

出力:

done
init

ベストアンサー1

おそらく、これを処理する最良の方法は、プライベート コンストラクターを呼び出すファクトリー関数を使用することです。

Dart では、プライベート メソッドはアンダースコアで始まり、"追加の" コンストラクターには という形式の名前が必要ですClassName.constructorName。これは、Dart が関数のオーバーロードをサポートしていないためです。つまり、プライベート コンストラクターには、アンダースコアで始まる名前が必要です (MyComponent._create以下の例では )。

import 'dart:async';
import 'dart:io';

class MyComponent{
  /// Private constructor
  MyComponent._create() {
    print("_create() (private constructor)");

    // Do most of your initialization here, that's what a constructor is for
    //...
  }

  /// Public factory
  static Future<MyComponent> create() async {
    print("create() (public factory)");

    // Call the private constructor
    var component = MyComponent._create();

    // Do initialization that requires async
    //await component._complexAsyncInit();

    // Return the fully initialized object
    return component;
  }
}

void main() async {
  var c = await MyComponent.create();

  print("done");
}

この方法により、クラスから不適切に初期化されたオブジェクトを誤って作成することは不可能になります。使用可能なコンストラクターはプライベートのみであるため、オブジェクトを作成する唯一の方法は、適切な初期化を実行するファクトリーを使用することです。

おすすめ記事