dart State.initState()必须是没有"async“关键字的void方法

icnyk63a  于 2023-01-15  发布在  其他
关注(0)|答案(1)|浏览(227)

![State.initState() must be a void method without an async keyword. how can i solve this probelms]1

@override
  Future<void> initState() async {
    // TODO: implement initState
    super.initState();
    _current_location();
    BitmapDescriptor.fromAssetImage(
        ImageConfiguration(devicePixelRatio: 2.5),
        'assets/fff.png').then((onValue) {
      pinLocationIcon = onValue;
    });
    //createCustomMarker(context);

   // final Marker marker = Marker(icon: BitmapDescriptor.fromBytes(markerIcon));
    DatabaseReference ref = FirebaseDatabase.instance.reference();
    ref.child('users').once().then((DataSnapshot snapshot) {
      Map<dynamic, dynamic> values = snapshot.value;
      print(values.toString());
      values.forEach((k, v) {
        allMarkers.add(Marker(
          markerId: MarkerId(k),
          draggable: false,
          icon: pinLocationIcon,
          position: LatLng(v["latitude"], v["longitude"]),
          infoWindow: InfoWindow(title: v["name"]),
          onTap: () {
            _onMarkerTapped(v["name"]);
          },
        ),);
      });
    });
  }
aor9mmx1

aor9mmx11#

initState * 必须 * 是一个不带参数并返回void的方法。这是因为它覆盖了超类中同名的方法(StatelessWidgetState<StatefulWidgetType>。因此,该限制是固定和绑定的约定;你无法改变它。
当然,这也意味着initState不能被标记为async,因为任何标记为async的方法都会隐式返回一个Future,但是如果该方法返回任何东西,它就不能有一个void的返回类型,这违反了重写契约。
如果你需要从initState中调用一个async方法,你可以通过不调用await来实现:

@override
void initState() {
  super.initState();
  
  doSomeAsyncStuff();
}

Future<void> doSomeAsyncStuff() async {
  ...
}

然而,如果你的小部件需要async方法中的数据,你不能简单地等待Future返回,然后再构建小部件。Flutter不允许这样做,因为不知道Future需要多长时间才能返回,并且在此之前停止构建小部件可能会阻塞你的整个应用。
相反,你需要让你的小部件正常构建,然后有一种方法来通知你的小部件在Future返回时更新,这在FutureBuilder中最容易做到:

@override
Widget build(BuildContext context) {
  return FutureBuilder(
    future: doSomeAsyncStuff(),
    builder: (context, snapshot) {
      if (!snapshot.hasData) {
        // Future hasn't finished yet, return a placeholder
        return Text('Loading');
      }
      return Text('Loading Complete: ${snapshot.data}');
    }
  );
}
  • (请注意,在构建过程中,我不是从initState调用async方法,而是从FutureBuilder调用它。)*

编辑:如前所述,这种方法只适用于OP的情况,即等待的future最终总是返回一个值。但情况并不总是如此--有时future根本不返回值,只是一个长时间运行的进程。有时future可能返回null而不是具体的数据。有时future可能导致错误而不是成功完成。在这些情况下,snapshot.data在future完成之后将为空,在这种情况下snapshot.hasData将总是为假。
在这些情况下,您可以使用snapshot.connectionState来监视将来的状态,而不是依赖于snapshot.hasData来等待数据出现:

@override
Widget build(BuildContext context) {
 return FutureBuilder(
   future: doSomeAsyncStuff(),
   builder: (context, snapshot) {
     if (snapshot.connectionState != ConnectionState.done) {
       // Future hasn't finished yet, return a placeholder
       return Text('Loading');
     }
     return Text('Loading Complete');
   }
 );
}

相关问题