I am having a problem with Flutter/Dart Async code execution, as in how does it work

后端 未结 1 1577

In Flutter we use async await and Future, can someone explain that if we don\'t use another thread (which we can\'t in dart) and run the job on main UIThread only won\'t the app

1条回答
  •  一向
    一向 (楼主)
    2021-01-24 19:42

    I think you missed something in asynchronous methods in Dart. Dart is a single threaded programming language, Java or C# are multi-threaded programming languages, forget async as a new thread, it doesn't happen in Dart. Dart is a single-threaded programming language. This means is that Dart can only run one instruction at a time while Java could run multiple instructions concurrently.

    As a rule, everything you do in Dart will start in UI-Thread. Whatever method you call in Dart, whether using sync, async, then, they will be running on UI-Thread, since Dart is a single thread. In single thread languages ​​like Javascript and Dart, an async method is NOT executed in parallel but following the regular sequence of events, handled by the Event Loop. There are some problems (I would say approaches, as we will see below), if you run the following code in a multithreaded language where fetch will take some time to execute:

    String user = new Database.fetch(David);
    String personalData = new Database.fetch(user);
    

    You will receive David's data in user, and after that, you will receive your data. This will lock your UI, and for that languages ​​like Java have Threads, which you can use to perform this task in the background, on another thread, and the UI-Thread will run smoothly.

    If you do this at Dart

    String user = new Database.fetch(David);
    String personalData = new Database.fetch(user);
    

    user will be null in personalData, because the fetch event is a Future.

    How to solve this in Dart?

    String user = await Database.fetch(David);
    String personalData = await Database.fetch(user);
    

    For those who like a more functional paradigm(I don't like it) you can use then.

    Database.fetch(David).then((user){
    Database.fetch(user).then((personal){
    String personalData = personal;
    });
    });
    

    However, imagine that you have billions of data in that database, this heavy task will probably cause the animations on your screen to freeze, and you will see a jank in the user's UI, for that isolates were invented.

    Dart Isolates give you a way to perform real multi-threading in Dart They have their own separate heaps(memory), and run the code in the background, just like the Threads of MultiThread languages. I could explain how isolates work, but it would make this response very big, and the goal is just to differentiate asynchronous/multithreaded methods.

    The way to solve the problem above, in a simple way, using isolates, would be using compute.

    Compute was created to facilitate the creation of isolates, you just pass the function and the data that that function will execute, and that's it! Important to remember that compute is a Future, so you have to use await or then to get the result of it.

    In our example, we could create a new thread and get the result of it when we finish just calling compute like this:

    String user = await compute(Database.fetch,David);
    String personalData = await compute(Database.fetch,user);
    

    Very simple, isn't it?

    Resume: Everything that waits some time to be completed, in the dart is called "Future". To wait for the result of a future to fill a variable, use await or then. The asynchronous methods(await and then) used to obtain a result from a Future are executed ON THE MAIN THREAD, because Dart is single-thread. If you want to run any function on a new thread, you can create an isolate. Dart offers an easy-to-use isolate wrapper called compute, where you only need to pass one method that will be processed, and the data that will be processed, and it will return you in the future the result of everything.

    • NOTE: if you are going to use compute make sure you are using a static or top level method (see that in the example I used Database.fetch it was no accident, if you need to call Database().fetch or need to create an instance of it, means it is not a static method and will not work with isolates).

    English is not my first language and I didn't want to write so much because of that, but I hope I helped differentiate multithreaded asynchronous programming from singlethread asynchronous programming.

    0 讨论(0)
提交回复
热议问题