de Mohammed Salman

Cum să aduceți o programare puțin asincronă la Dart cu futures

Cum sa aduceti o programare putin asincrona la Dart cu
„Proiectat de fullvector / Freepik”

Programarea asincronă este o formă de programare paralelă care permite unei unități de lucru să ruleze separat de firul principal de aplicație. Când lucrarea este finalizată, notifică firul principal (precum și dacă lucrarea a fost finalizată sau eșuată). Există numeroase avantaje în utilizarea acestuia, cum ar fi performanța îmbunătățită a aplicației și capacitatea de reacție îmbunătățită.

Postat inițial pe blogul meu.

TL; DR.

Problemă

Codul Dart rulează într-un singur fir de execuție, deci dacă este blocat, întregul program se blochează.

Exemplu:

//..
var data = fetchDataFromSomeApi(); // Takes time while fetching data
doStuffWithData(data); // Manipulate the data
doOtherStuff(); // Do other stuff unrelated to the data
//..

De cand fetchDataFromSomeApi() blocuri, codul rămas rulează numai după fetchDataFromSomeApi() revine cu datele, oricât de mult ar dura.

Acest cod rulează linie cu linie determinând oprirea codului și doOtherStuff() pentru a rula după ce operațiunea de preluare a datelor este terminată (ceea ce probabil nu este ceea ce doriți).

Soluţie

Operațiile asincrone vă permit programului să finalizeze alte lucrări în timp ce așteptați finalizarea altei operații.

Același exemplu ca mai sus, dar cu o abordare asincronă:

fetchDataFromSomeApi().then((data) {  print('Fetched data');  doStuffWithData(data);});
print('Working on other stuff...');doOtherStuff();
// Output://   Working on other stuff...//   Fetched data

fetchDataFromSomeApi nu este blocant, ceea ce înseamnă că permite altor coduri să ruleze în timp ce preluează date. De aceea nivelul superior print declarația rulează înainte de print declarație în funcția de apel invers.

Futures

Un viitor reprezintă un calcul care nu se finalizează imediat. În cazul în care o funcție normală returnează rezultatul, o funcție asincronă returnează un viitor, care va conține în cele din urmă rezultatul. Viitorul vă va spune când rezultatul este gata.

Future obiecte (viitor) reprezintă rezultatele operații asincrone – procesare sau I / O care urmează să fie finalizate ulterior.

Putem crea un viitor pur și simplu așa:

Future future = Future();

să definim o funcție numită f:

String f() => 'work is done!';

și transmite-l la viitor:

Future<String> future = Future(f);

Observați că viitorul are același tip de funcție f tip retur String.

În scopul acestui tutorial am trecut o funcție care returnează doar un șir. Acest lucru creează un viitor care conține rezultatul apelului f asincron cu Timer.run.

Dacă rezultatul executării f aruncă, viitorul returnat este completat cu eroarea.

Dacă valoarea returnată este ea însăși a Future, finalizarea viitorului creat va aștepta până când viitorul returnat se va finaliza și va finaliza cu același rezultat.

Dacă se returnează o valoare non-viitoare, viitorul returnat este completat cu acea valoare.

atunci

Hai sa sunăm then pe viitor și treceți o funcție care ia ieșirea operației asincrone ca argument

future.then((String val) => print(val)); // work is done

îl putem simplifica prin trecerea print funcționează numai pentru că ia un șir

future.then(print); // work is done

Eroare de manipulare

Pentru a prinde erori, utilizați expresii try-catch în funcțiile asincronizate (sau utilizați catchError()).

catchError

să ne imaginăm că viitorul nostru aruncă o eroare la un moment dat:

Future future = Future(() => throw Error());

Dacă sunăm then pe viitor fără a gestiona eroarea, va arunca eroarea și va opri executarea programului nostru:

future.then(print); // Error: Error: Instance of 'Error'

Să definim o funcție care ia o eroare și o gestionează:

void handleError(err) { print(‘$err was handled’);}

apoi atașați catchError() spre viitor și treceți handleError:

future.then(print).catchError(handleError); // Error: Error: Instance of 'Error' was handled

În acest fel, eroarea este tratată și programul continuă să se execute.

Async, Await

Pentru a suspenda execuția până la finalizarea unui viitor, utilizați await într-o funcție asincronă (sau utilizați then()).

Pentru a utiliza await cuvânt cheie, trebuie să fie în interiorul unui async funcționează astfel:

main() async { Future future = Future(() => ‘work is done’); String res = await future; print(res); // work is done}

Observați că main funcția este marcată cu async cuvânt cheie.

Orice funcție marcată cu async se numește asincron.

Când numim un viitor cu await cuvânt cheie, executarea funcției este oprită până când future returnează o valoare sau aruncă o eroare.

Putem gestiona erorile viitoare folosind un trycatch bloc:

main() async { Future future = Future(() => throw Error()); try {   print(await future);  } catch (e) {   print(‘$e was handled’); // Instance of 'Error' was handled }}

Concluzie

  • Codul Dart rulează într-un singur „fir” de execuție.
  • Codul care blochează firul de execuție vă poate îngheța programul.
  • Future obiecte (viitor) reprezintă rezultatele operații asincrone – procesare sau I / O care urmează să fie finalizate ulterior.
  • Pentru a suspenda execuția până la finalizarea unui viitor, utilizați await într-o funcție asincronă (sau utilizați then()).
  • Pentru a prinde erori, utilizați expresii try-catch în funcțiile asincronizate (sau utilizați catchError()).

Dacă simți că mi-a fost dor de ceva aici, te rog, anunță-mă sau dacă ai vreo întrebare, poți să mă contactezi stare de nervozitate.

Abonați-vă la newsletter-ul meu!

Alte resurse utile

Programare asincronă: Futures