在Flutter中等待未来函数完成后再继续。

huangapple go评论67阅读模式
英文:

waiting for future function to finish before proceeding in flutter

问题

我有一个在Flutter中的Future函数。我希望在Flutter可以继续执行下一行代码之前,该Future函数能够完成执行。我正在使用`future.wait`,但似乎对我不起作用。我还尝试创建独立的函数,并添加`async`和`await`,然后在构造函数中调用该函数,但也不起作用。

以下是我的代码:

这是一个用于保持可以通过许多类访问的对象的单例类。
在构造函数中,我使用`future.wait`来等待函数完成。

```dart
import 'package:flutter/cupertino.dart';
import '../repositories/objectbox_store.dart';
import 'package:flutter/material.dart';

class ObjectService {
  late ObjectBox objectBox;
  static final ObjectService _instance = ObjectService._internal();

  // 将实例化传递给_instance对象
  factory ObjectService() => _instance;

  // 在这里初始化变量
  ObjectService._internal()  {
    Future.wait([
      initializeObject()
    ]);
  }

  // 获取我的变量的简短getter
  ObjectBox get myVariable => objectBox;

  Future<void> initializeObject() async {
    // 这是必需的,以便ObjectBox可以获取应用程序目录
    // 以存储数据库。
    WidgetsFlutterBinding.ensureInitialized();
    objectBox = await ObjectBox.create();
  }
}

以下是我的调用类:

class ViewTransaction extends StatefulWidget {
  ViewTransaction({
    Key? key,
    required this.isSearch,
    required this.transactionType
  }) : super(key: key);

  final bool isSearch;
  final String transactionType;

  @override
  State<StatefulWidget> createState() {
    return ViewTransactionState();
  }
}

class ViewTransactionState extends State<ViewTransaction> {
  int count = 0;
  // ViewTransactionSummaryBloc get bloc => Provider.of<ViewTransactionSummaryBloc>(context);
  late Stream<List<Income>> _stream;

  @override
  Widget build(BuildContext context) {
   
    return Scaffold(
        floatingActionButton: FloatingActionButton(
          backgroundColor: colorPrimary,
          onPressed: () {
            Navigator.push(context,
                MaterialPageRoute(builder: (context) => const AddEditIncomeForm( addEditIndicator: 'Add')));
          },
          child: Icon(
            Icons.add,
          ),
        ),
        body: incomeSummaryStream()
    );
  }

  Widget incomeSummaryStream()  {
    ObjectService _myService =  ObjectService();

    Stream<List<Income>> _stream =  _myService.myVariable.store
        .box<Income>()
        .query()
        .watch(triggerImmediately: true)
        .map((query) => query.find());
  }
}

我在ViewTransaction类中调用了ObjectService _myService = ObjectService()
我希望ObjectService中的Future在继续执行下一行之前完成,即:

Stream<List<Income>> _stream =  _myService.myVariable.store

当我尝试访问_myService.myVariable.store时,我收到以下错误:

在Flutter中等待未来函数完成后再继续。

请帮忙查看一下。我在这里做错了吗?


<details>
<summary>英文:</summary>

i have a future function in flutter. I want the future function to finish executing before flutter can move to the next line of code. I am using future.wait but it looks like it is not working for me. i also try to create independent function and add async and await and then call that function in the constructor but it is not working either.

here is my code

this is a singleton class to keep an object that will be access through many classes.
in the constructor i am using future.wait to wait for the function to finish .

import 'package:flutter/cupertino.dart';
import '../repositories/objectbox_store.dart';
import 'package:flutter/material.dart';

class ObjectService {
late ObjectBox objectBox;
static final ObjectService _instance = ObjectService._internal();

// passes the instantiation to the _instance object
factory ObjectService() => _instance;

//initialize variables in here
ObjectService._internal() {

Future.wait([
    initializeObject()
  ]);

}

//short getter for my variable
ObjectBox get myVariable => objectBox;

Future<void> initializeObject () async {
// This is required so ObjectBox can get the application directory
// to store the database in.
WidgetsFlutterBinding.ensureInitialized();
objectBox = await ObjectBox.create();
}
}


here is my calling class

class ViewTransaction extends StatefulWidget {
ViewTransaction({
Key? key,
required this.isSearch,
required this.transactionType
}) : super(key: key);

final bool isSearch;
final String transactionType;

@override
State<StatefulWidget> createState() {
return ViewTransactionState();
}
}

class ViewTransactionState extends State<ViewTransaction> {
int count = 0;
//ViewTransactionSummaryBloc get bloc => Provider.of<ViewTransactionSummaryBloc>(context);
late Stream<List<Income>> _stream;

@override
Widget build(BuildContext context) {

return Scaffold(
    floatingActionButton: FloatingActionButton(
      backgroundColor: colorPrimary,
      onPressed: () {
        Navigator.push(context,
            MaterialPageRoute(builder: (context) =&gt; const AddEditIncomeForm( addEditIndicator: &#39;Add&#39;)));
      },
      child: Icon(
        Icons.add,
      ),
    ),
    body:  incomeSummaryStream()
);

}

Widget incomeSummaryStream() {
ObjectService _myService = ObjectService();

Stream<List<Income>> _stream = _myService.myVariable.store
.box<Income>()
.query()
.watch(triggerImmediately: true)
.map((query) => query.find());
}


i am calling    ObjectService _myService =  ObjectService() in ViewTransaction  class.
i am expecting the future in ObjectService to finish before moving to the next line which is

Stream<List<Income>> _stream = _myService.myVariable.store


when i try to access _myService.myVariable.store, i get the following error

[![enter image description here][1]][1]


  [1]: https://i.stack.imgur.com/srGxW.png

please help. am i doing something wrong here?

</details>


# 答案1
**得分**: 0

我们不能在构造函数中使用 `Future`。构造函数必须始终是同步的。

或者,您可以创建一个特殊的方法,在首次使用之前初始化对象并调用它。
示例:

```dart
class ObjectService {
  static final ObjectService instance = ObjectService._();

  late final ObjectBox _objectBox;

  ObjectService._();

  ObjectBox get objectBox => _objectBox;

  Future<void> init() async {
    _objectBox = await ObjectBox.create();
  }
}

在您的 main 函数中(main 函数需要变成异步):

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();

  // 等待 [ObjectService] 初始化完成
  await ObjectService.instance.init();

  runApp(const MyApp());
}

希望这对您有所帮助。

英文:

We can't use Future in constructors. Constructors must always be synchronous.

Alternatively, you can make a special method that would initialize your object and call it before the first use.
Example:

class ObjectService {
  static final ObjectService instance = ObjectService._();

  late final ObjectBox _objectBox;

  ObjectService._();

  ObjectBox get objectBox =&gt; _objectBox;

  Future&lt;void&gt; init() async {
    _objectBox = await ObjectBox.create();
  }
}

And in your main function (the main function needs to be made asynchronous):

Future&lt;void&gt; main() async {
  WidgetsFlutterBinding.ensureInitialized();

  // Waiting for [ObjectService] to be initialized
  await ObjectService.instance.init();

  runApp(const MyApp());
}

huangapple
  • 本文由 发表于 2023年6月11日 22:12:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/76450883.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定