-2

My function is as follows:

void function() async {
  …
}

I used the above function in Widget build(BuildContext context).

Actually, I want it to be Future<void> function() async instead of void function() async.

However, I can't use await in Widget build(BuildContext context), so I can't use Future<void> function() async because Future requires await.

I shouldn't use FutureBuilder or then because I don't want to get the data in the function, I just want to run the function.

Appreciate if someone can advise. Thank you in advance!

My Car
  • 4,198
  • 5
  • 17
  • 50
  • 6
    If your `build` method depends on a `Future`, it should be using a [`FutureBuilder`](https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html). – jamesdlin Oct 01 '22 at 05:08
  • 1
    If FutureBuilder is not what you need, you can also use "then" to resolve future without using await – Sanketh B. K Oct 01 '22 at 06:01
  • @jamesdlin I shouldn't use `FutureBuilder` because I don't want to get data in a function, I just want to run that function. – My Car Oct 01 '22 at 06:40
  • @SankethB.K I shouldn't use `then` because I don't want to get data in a function, I just want to run that function. – My Car Oct 01 '22 at 06:41
  • 2
    @MyCar Then what problem are you trying to solve? If you don't need to wait for that asynchronous function to complete, then just call it as a fire-and-forget function, and it will complete at some indeterminate point in the future. (Doing that from a `build` method sounds likely to be inappropriate though.) – jamesdlin Oct 01 '22 at 06:47
  • @jamesdlin So, can `Future` functions not need `await`? – My Car Oct 01 '22 at 07:02
  • 2
    If you do not need to wait for your asynchronous function to complete, either it can return `void` or the caller can just ignore the returned `Future`. – jamesdlin Oct 01 '22 at 07:22

2 Answers2

1

build method can run up to 60(maybe more with the newest phones)times per second, so it's not a good idea to run any heavy computation or API call in the build method. It's simply for building(widgets).

You may want to rethink your app architecture if you think you must.

Consider bloc pattern or just checkout other lifecycle methods for stateful widgets. This article has a list of them.

As for the question, async functions technically don't require you to await them. You can just call them without adding await in front of them.

If you have a warning, it might be coming from lint rules. Related rule.

mirkancal
  • 4,762
  • 7
  • 37
  • 75
  • So, do you mean that I should execute the function in `initState` in `StatefulWidget`? – My Car Oct 01 '22 at 07:05
  • I have no idea what kind of function you're running or what feature you are implementing. A code example would be good. But as a general thumb of rule, build method is for building things and should be cheap. It can run so many times(e.g animations). If you want to do an async operation, do it in the initState, and build your UI with FutureBuilder when it's ready. If it's not related to UI, simply write a service class. https://docs.flutter.dev/perf/best-practices#control-build-cost – mirkancal Oct 01 '22 at 07:08
  • Excuse me, can I change `void initState()` to `Future initState() async` ? – My Car Oct 01 '22 at 07:22
  • No, but you can put all the calls in another function, which is async. And then call that in initState. But you can't await this function, too since initState is not async. – mirkancal Oct 01 '22 at 07:27
  • Excuse me, can I use `void function() async`? – My Car Oct 01 '22 at 11:19
1

You can define your function as future & call it in initState of StatefulWidget (without await)

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {

    Future<void> myFutureFunction() async {
      // some future work with
    }

  @override
  void initState() {
    super.initState();
    // this will be called once, when this widget is apear to the screen
    myFutureFunction();
  }

  @override
  Widget build(BuildContext context) {
    return SizedBox();
  }
}
Abhishek Patil
  • 180
  • 1
  • 9