дротик ждут на конструкторе - PullRequest
0 голосов
/ 06 февраля 2019

Какой шаблон мне следует использовать в этом примере для загрузки и обработки некоторых данных.Поскольку value возвращает значение, недопустимо иметь d в качестве Future.Как я могу заставить конструктор дождаться завершения load, прежде чем продолжить?

void main() {
    var data = new Data(); // load data
    print(data.value()); // data.d is still null
}

class Data {
    String d;
    Data() {
        load();
    }

    Future<void> load() async {
        d = await fn(); // some expensive function (e.g. loading a database)
    }

    String value() {
        return d;
    }
}

1 Ответ

0 голосов
/ 06 февраля 2019

Вы не можете сделать конструктор асинхронным.Асинхронная функция должна возвращать Future, а конструктор должен возвращать экземпляр самого класса.Если класс не является будущим, конструктор не может быть асинхронным (и даже тогда это не совсем то же самое, и вы не можете использовать async / await).

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

class Data {
  String _d;
  Data._();
  static Future<Data> create() async {
    var data = Data._();
    await data._load();
    return data;
  }
  Future<void> _load() async {
    _d = await fn(); 
  }
  String get value => _d;
}

В качестве альтернативного дизайна я бы даже не поместил метод load в класс, просто выполнил бы операцию в статическом фабричном методе:

class Data {
  String _d;
  Data._(this._d);
  static Future<Data> create() async => Data._(await fn());
  String get value => _d;
}

Очевидно, что другие ограничения могут потребовать, чтобы load имел доступ к объекту.

...