Πώς να εφαρμόσετε την ασύγχρονη επεξεργασία Flutter

Καθώς οι περισσότερες εφαρμογές smartphone παραγωγής έχουν πρόσβαση σε DB και API, απαιτείται ασύγχρονη επεξεργασία.

Υπάρχουν δύο Widgets Async στο Flutter Official site.

https://flutter.io/widgets/async/

Δεδομένου ότι είμαι αρχάριος στο Dart and Flutter, δεν ξέρω ποιο να χρησιμοποιήσω, αλλά πρώτα έγραψα να χρησιμοποιήσω το StreamBuilder. Μετά από αυτό βρήκα ποια από αυτές θα χρησιμοποιηθεί εξαρτάται από την περίπτωση.

Θα περιγράψουμε την ασύγχρονη επεξεργασία του Dart πριν τη μέθοδο γραφής του Flutter.

Ασύγχρονη επεξεργασία βέλη

Το βελάκι έχει πολλά είδη ασύγχρονης γραφής.

Όλα τα ίδια αποτελέσματα από ① έως ⑦. Μπερδευτήκαμε όταν το είδα.

Για να ολοκληρωθεί νωρίτερα, μπορεί να αποφασιστεί ως εξής.

Σε αυτό το παράδειγμα, το ③ μπορεί να εκτελεστεί παράλληλα και αποτελεσματικά.

Θα εξηγήσω γιατί μοιάζει με αυτόν τον αριθμό.

Μελλοντικό ή Ρεύμα

Μπορείτε να βρείτε αυτή τη διαφάνεια.

Το API που χρησιμοποιείται εξαρτάται από τον αριθμό που πρέπει να επιστραφεί έτσι.

Εάν χτυπήσετε ένα σταθερό API και εμφανίσετε μόνο το αποτέλεσμα, χρησιμοποιήστε το Future. Αν αλλάξετε την προβολή από ένα συμβάν UI όπως ένα κλικ, χρησιμοποιήστε το Stream.

Δεδομένου ότι το Stream μπορεί επίσης να επιστρέψει μία τιμή, μπορεί επίσης να κάνει όλο το Stream. Ωστόσο, είναι απαραίτητο να σκεφτούμε πόσες αξίες θα επιστραφούν κατά τη χρήση αυτής της συνάρτησης και να αυξηθεί ο σπάταλος κώδικας. Ως εκ τούτου, νομίζω ότι πρέπει να χρησιμοποιήσετε κάτι πιο κατάλληλο για την κατάστασή σας.

Μέλλον  asyncFunc () async {
  επιστροφή "async επιστροφή"?
}}
var asyncResult = περιμένετε asyncFunc ();
εκτύπωση (asyncResult);
// vs
Stream  streamFunc () async * {
  απόδοση "ροή επιστροφή"?
}}
streamFunc () ακούστε ((αποτέλεσμα) {
  εκτύπωση (αποτέλεσμα)?
});

Αυτό σας επιτρέπει να επιλέξετε αν θα χρησιμοποιήσετε το FutureBuilder ή το StreamBuilder ανάλογα με την κατάστασή σας.

Ας γνωρίσουμε λίγο περισσότερα σχετικά με την ασύγχρονη επεξεργασία της Dart.

"Περιμένετε" ή "ακούσετε ()"

Στις περισσότερες περιπτώσεις, είναι πιο εύκολο να γράψετε χρησιμοποιώντας αναμονή.

εισαγωγή "βέλος: async";
εισαγωγή 'dart: io';
Εισαγωγή 'βέλος: μαθηματικά'.

main () async {
  περιμένετε για (var tick στο endlessCountDown ()) {
    εκτύπωση ("coutDown $ tick");
  }}
// endlessCountDown () ακούστε ((tick) {
// print ("coutDown $ tick");
//});
}}

Ροή  endlessCountDown () async * {
  var i = pow (2, 30) -1;
  ενώ (αληθής) {
    ύπνος (νέα διάρκεια (δευτερόλεπτα: 1)).
    απόδοση ι -;
  }}
}}

Ας δούμε ένα παράδειγμα όπου υπάρχουν δύο ροές ως εξής.

Εάν θέλετε να ακούσετε δύο ροές, δεν μπορείτε να δείτε τα αρχεία καταγραφής "countUp".

Επειδή περιμένετε για δεν μετακινείται στον επόμενο κώδικα εκτός και αν τελειώσει η ροή.

εισαγωγή "βέλος: async";
εισαγωγή 'dart: io';
Εισαγωγή 'βέλος: μαθηματικά'.

main () async {
  περιμένετε για (var tick στο endlessCountDown ()) {
    εκτύπωση ("coutDown $ tick");
  }}
  περιμένετε για (γραμμή var στο endlessCountUp ()) {
    εκτύπωση ("countUp $ line")?
  }}
}}

Ροή  endlessCountUp () async * {
  var i = 0.
  ενώ (αληθής) {
    ύπνος (νέα διάρκεια (δευτερόλεπτα: 1)).
    απόδοση ί ++.
  }}
}}

Ροή  endlessCountDown () async * {
  var i = pow (2, 30) -1;
  ενώ (αληθής) {
    ύπνος (νέα διάρκεια (δευτερόλεπτα: 1)).
    απόδοση ι -;
  }}
}}

Μπορείτε να ακούσετε κάθε μία από τις μεθόδους διαχωρισμού ως εξής. Αλλά ... είναι αυτό εύκολο να διαβαστεί;

εισαγωγή "βέλος: async";
εισαγωγή 'dart: io';
Εισαγωγή 'βέλος: μαθηματικά'.

main () {
  listenCountDown ();
  listenCountUp ();
}}

listenCountDown () async {
  περιμένετε για (var tick στο endlessCountDown ()) {
    εκτύπωση ("coutDown $ tick");
  }}
}}

listenCountUp () async {
  περιμένετε για (var tick στο endlessCountUp ()) {
    εκτύπωση ("coutUp $ tick");
  }}
}}
...

Σε αυτή την περίπτωση, είναι καλύτερο να χρησιμοποιήσετε απλά την εντολή listen ().

εισαγωγή "βέλος: async";
εισαγωγή 'dart: io';
Εισαγωγή 'βέλος: μαθηματικά'.

main () {
  endlessCountDown () ακούστε ((tick) {
    εκτύπωση ("coutDown $ tick");
  });
  endlessCountUp () ακούστε ((σημειώστε) {
    εκτύπωση ("coutUp $ tick");
  });
}}
...

Εάν το γράφετε αναμένοντας και αν φαίνεται να είναι περιττό, θα πρέπει να χρησιμοποιήσετε καλύτερα την ακρόαση ().

Μπορείτε να ελέγξετε το επίσημο έγγραφο σχετικά με αυτό.

Περιήγηση στις Βιβλιοθήκες Dart

"Περιμένετε" ή "τότε ()" ή "περιμένετε το Future.wait ()"

// ①
asyncFunc1 (), τότε (() => asyncFunc2 ()), τότε ((αποτέλεσμα) {
  εκτύπωση (αποτέλεσμα)?
});

// ②
var asyncResult1 = περιμένει asyncFunc1 ();
var asyncResult2 = περιμένει asyncFunc2 ();
εκτύπωση (asyncResult2);

// ③
var list = περιμένει Future.wait ([asyncFunc1 (), asyncFunc2 ()]);
εκτύπωση (κατάλογος [1]);

Ας αρχίσουμε με "αναμονή" ή "τότε ()" (① ή ②).

Αναφέρεται στο Effective Dart ως εξής.

Η συνένωση async / await βελτιώνει την αναγνωσιμότητα και σας επιτρέπει να χρησιμοποιείτε όλες τις δομές ροής ελέγχου Dart μέσα στον κωδικό σας async.

Νομίζω ότι αν μπορείτε να χρησιμοποιήσετε async / await, θα πρέπει να το χρησιμοποιήσετε. Έτσι, ας περιμένουμε.

Στη συνέχεια, ας δούμε "περιμένουν" και "περιμένουν Future.wait ()".

// ②
Χρονόμετρο χρονόμετρου1 = Νέο Χρονόμετρο () .. αρχή ();
var asyncResult1 = περιμένει asyncFunc1 ();
var asyncResult2 = περιμένει asyncFunc2 ();
εκτύπωση (asyncResult2);
print ('await () εκτελείται σε $ {stopwatch1.elapsed}');

// ③
Χρονομετρητής χρονόμετρου2 = Νέο Χρονόμετρο () .. αρχή ();
var list = περιμένει Future.wait ([asyncFunc1 (), asyncFunc2 ()]);
εκτύπωση (κατάλογος [1]);
print ('Future.wait () εκτελέστηκε στο $ {stopwatch2.elapsed}');
Μελλοντικό  asyncFunc1 () async {
  επιστρέφει νέα Future.delayed (const Διάρκεια (δευτερόλεπτα: 1), () => "async return1");
}}

Μέλλον  asyncFunc2 () async {
  επιστρέφει νέα Future.delayed (const Διάρκεια (δευτερόλεπτα: 1), () => "async return2");
}}

Όπως μπορείτε να δείτε από αυτή τη σύγκριση, αν κάθε Μέλλον μπορεί να εκτελεστεί ταυτόχρονα, είναι προτιμότερο να χρησιμοποιήσετε το Future.wait () καθώς μπορεί να εκτελεστεί νωρίτερα.

Πώς μπορώ να χρησιμοποιήσω το FutureBuilder;

Μπορείτε να ελέγξετε τον πηγαίο κώδικα

δείγμα εφαρμογής
@καταπατώ
Δημιουργία εικονιδίου widget (περιβάλλον BuildContext) {
  επιστροφή νέου υλικούApp (
    τίτλο: 'Demo Flutter',
    θέμα: νέα στοιχεία θέματος (
      primarySwatch: Colors.blue,
    ),
    Αρχική: νέο FutureBuilder (μελλοντικό: νέο Μέλλον (() async {
      var token = περιμένει AccessToken.getInstance (). getOrCreate ();
      var χρήστη = περιμένει fetchUser (token);
      επιστροφή περιμένει fetchEvents (χρήστης, συμβόλαιο);
    }), οικοδόμος: (περιβάλλονContextContext, AsyncSnapshot  feedState) {
      αν (feedState.error! = null) {
        // TODO: χειρισμός σφαλμάτων
      }}
      αν (feedState.data == null) {
        επιστροφή νέου Κέντρου (παιδί: νέος Κυκλικός Προωθητής Ισοτιμίας ());
      }}
      επιστροφή νέου MyHomePage (
          τίτλος: 'Demo Flutter Αρχική Σελίδα', εκδηλώσεις: feedState.data);
    }),
    // Αυτό το τελικό κόμμα κάνει την αυτόματη μορφοποίηση καλύτερο για τις μεθόδους δημιουργίας.
  ) ·

συμπέρασμα

Μπορείτε να αποφασίσετε ποιος ασύγχρονος μηχανισμός θα χρησιμοποιηθεί σύμφωνα με αυτό το διάγραμμα.
Δεδομένου ότι είμαι ένας αρχάριος Flutter, παρακαλώ να τονίσω τίποτα αν κάνω κάτι λάθος.