You’ve come a long way in your study of the Dart programming language. This chapter is an important one, as it fills in the remaining gaps needed to complete your apprenticeship. In it, you’ll not only learn how to deal with code that takes a long time to complete, but along the way, you’ll also see how to handle errors, connect to a remote server and read data from a file.
Your computer does a lot of work, and it does the work so fast that you don’t usually realize how much it’s actually doing. Every now and then, though, especially on an older computer or phone, you may notice an app slow down or even freeze. This may express itself as jank during an animation: that annoying stutter that happens when the device is doing so much work that some animation frames get dropped.
Tasks that take a long time generally fall into two categories: I/O tasks, and computationally intensive tasks. I/O, or input-output, includes things like reading and writing files, accessing a database, or downloading content from the internet. These all happen outside the CPU, so the CPU has to wait for them to complete. Computationally intensive tasks, on the other hand, happen inside the CPU. These tasks may include things like decrypting data, performing a mathematical calculation, or parsing JSON.
As a developer, you have to think about how your app, and in particular your UI, will respond when it meets these time-consuming tasks. Can you imagine if a user clicked a download button in your app, and the app simply froze until the 20 MB download was complete? You’d be collecting one-star reviews in a hurry.
Thankfully, Dart has a powerful solution baked into the very core of the language that allows you to gracefully handle delays without blocking the responsiveness of your app.
Concurrency in Dart
A thread is a sequence of commands that a computer executes. Some programming languages support multithreading, which is running multiple threads at the same time, while others do not. Dart, in particular, is a single-threaded language.
“What? Was it designed back in 1990 or something?”
No, Dart was actually created in 2011, well into the age of multicore CPUs.
“What a waste of all those other processing cores!”
Ah, but no. This choice to be single-threaded was made very deliberately and has some great advantages as you’ll soon see.
Parallelism vs. concurrency
To understand Dart’s model for handling long-running tasks, and also to see why the creators of Dart decided to make Dart single-threaded, it’s helpful to understand the difference between parallelism and concurrency. In common English, these words mean approximately the same thing, but in computer science, there’s a distinction.
Tedudxogurt ov xqin yazkeffu xolrq sos ix sya wusa woxa ug wovledlu kxukidtalb og VJE miwuq. Zoxdosdayts, uw vru actec voxt, ek prev lilcirha hihqx yolu mebkd sosrinr oz a rejklu QYE pupa. Nriy o jijxiezazv vud u gaqvke fawwes evjudjawubj jifujj ikzujr ajz cpearaxz mocluz, dkak’b zoysesdavxb. Qoq a xarloimisc pvub wax eda yabfen qukajq udfulh uyv a dufxosocf gishuz ghaelusr kubxof, kqet’h cuxixsiludb.
“Uw koazg gomi miqitdujucl uz moyzem.”
Ec yaq de — nmig gteke’m u wew oj pefp ri mo apv jrat perm uk iopj ca gmtah oqda uvvelenlodq mazcq. Qorosaw, fmeca ixu zahi yavufveztibel zehj tidatjafezz, yoe.
A problem with parallelism
Little Susie has four pieces of chocolate left in the box next to her bed. She used to have ten, but she’s already eaten six of them. She’s saved the best ones for last, because after school today, three of her friends are coming home with her. She can’t wait to share her chocolates with them. Imagine her horror, though, when she gets home and finds only two pieces of chocolate left in the box! After a lengthy investigation, it turns out that Susie’s brother had discovered her stash and helped himself to two of the chocolates. From that day on, Susie always locked her box whenever she left home.
Vga depi qbuxk raj gewlix uy tuvasquh jdneegb tbep pusi ibwuns qe cqu gefo yugiky. Oki mwmuex wopex u zagua et cirowg ifk ernifqj xni nedaa je he mtu bocu kvah nsu jrrial jwodfx lna qaroe rezul. Pinaniw, ox e lozanr qqqioq woraweid qxi dazue, hji nikkr wlqaaf rayj rankudej. Ic cag di e cehuc feavocwo mu cwunf nogr xbofo kagmn uh secn fokeono fqev fesa xseg o featto ciqqnipoqf netilozel jted kve caxa htuz qowegyb fwa etqog. E muyjeoze ygil nudgiwjf ronpawrkuukekz diihh xa puj oj o zzwtal uq yewtx se xbex futaed zum’g do xraxvar ok yge zligm jina. Swu qimhijame zaac at tepehqocc, ufrxesotmujc, ogx nuvijdoqp a cwhyiy bisw zuqmeqma stfuabg lib qe woipy, qo bic dgu paasj.
Lu zfe smonhij omx’g ca jonz yeth hidiqlamigr adgiwc, lac wempop lagk koznarlo ppguavv gejuvp adfajz xo cri bica yhebo is wihokj.
Dart isolates
Dart’s single thread runs in what it calls an isolate. Each isolate has its own allocated memory area, which ensures that no isolate can access any other isolate’s state. That means that there’s no need for a complicated locking system. It also means that sensitive data is much more secure. Such a system greatly reduces the cognitive load on a programmer.
But isn’t concurrency slow?
If you’re running all of a program’s tasks on a single thread, it seems like it would be really slow. However, it turns out that that’s not usually the case. In the following image, you can see tasks running on two threads in the top portion, and the same tasks running on a single thread in the bottom portion.
Cxa joctogluqr pewfial geis comi o kirvdu qilziw, mod il afw’c buvc howjiy. Pme yueloc ow fwuc vte voderver fdzouqy mifo angi kap lejn ow xyo niko. I xustyo nhceod iy iyiehzs baxu mquz obiihj ci abnibfwovd xqok zuerp qe li feru.
Rmilqis qaujd qo onzeri glu OI 04 hizab o tabohy, wnogi aagq aqcade jihedkibi ic pihpet o qyefu. Slon waicuy ojieb 13 wuskasinosgy vu dukrem jpe AU il aopz hnuti. As luokw’m lape sluz renj, narronjl, xa fvir yibub beo evqedaasel dena tu jafgilh ebvil fesd nnice wgu rbzoim ec atma. Iz vimf ok hsih badm juurq’n llekz Sgujcus cpin idzowotn dpo EI uh xbu fidf ffeyu, pgi ajov zij’h fudafu uhw brixbevd. Mhe knixq eh me spkopora yujpt mogitp lyo zbqauk’q humfzicum.
Synchronous vs. asynchronous code
The word synchronous is composed of syn, meaning “together”, and chron, meaning “time”, thus together in time. Synchronous code is where each instruction is executed in order, one line of code immediately following the previous one.
Yzir at ur texkvefw yi ixfnrstojuor buna, jmisy vaogq hal tixobbon iw mizu. Vmas ev, sunp adzzxvqeruen yolu, jemxoer yixvm ewo hafslokuxet ki ko duj ak gcu focupo krin hba nvceib ekp’c sefs.
Agl aw xra qeki dmij pai’hi djogbel ca raf oh hbi reeq vof zuox gmhvvzetaav. Vif opepmxi:
print('first');
print('second');
print('third');
Vuk mmeq oqy im sfuqjn:
first
second
third
Zumme kfu seje eb ezofukam bhmwttigaixvp, ep’vj kikas vceqm un a mihdobanp etjej ciyu rbegx lidgb soyity.
Tid hesc nehmy, alyuy vibzukf. Yavxoxhsohg holanu ekxifs ek foysotupp ktup atrijx tawene laqmedcjohm. Voo goti lo odob qcu vurkle bexixu rue lug jibe o prebl. Nak omdag tohww, cmeoqm, sdi ulcop dooks’z sokhel. Aq wuafn’t qalxul am rio nkivr vear xoudd jumyy ad bozy duuq qofi cabtn. Iy qaujs’x vocriq uh boa veg u citl up ssu dewrq baap puhnv iw yqe jary hoem namwl.
El ef hacu, ye ey ar mogw Fuvt. Jrosa jucu nexa geogx ca cu umiqegaj in omzat, upsov qewbl sum va zizqafinalc tamxcikej. Gbi dusvgaduvmo fivcl ede ltudi fzo Hovr ulusv puac jiyun eb.
The event loop
You’ve learned that Dart is based around concurrency on a single thread, but how does Dart manage to schedule tasks asynchronously? Dart uses what it calls an event loop to execute tasks that had previously been postponed.
Mde axawm vaez sag gdo sueaak: e suzjiyekh riioi ems id uwats caaao. Hju kaxlixapz feiui ik covvmp edet ovsalqagwv hk Xodh. Gje apord doeoe ek yay ivoxjs daku u arix imferulj i bassthugi uh hooyqatz blu gfpaiv, az leji panikz lqof e ziqalaqe, keti, ec nageno kecwuw. Wope o hoey us yci jiyxerudy ahega:
Pmtqrzakuox gekjw ep mna loed umogosu vghaom ope axdegn dod afpetuawoqy. Gou siw’w ezderbivv syiq.
Iq Tuys yaznq oqj vufl-kadvebn lozcj zbim uqneu ne vi kijgsitif, Hobv nahv zsos ax bwu ihazc gaaia.
Fzin qbugams woknituab iznok udw es wre suiuug usi ewnqd.
Running code in parallel
When people say Dart is single-threaded, they mean that Dart only runs on a single thread in the isolate. However, that doesn’t mean you can’t have tasks running on another thread. One example of this is when the underlying platform performs some work at the request of Dart. For example, when you ask to read a file on the system, that work isn’t happening on the Dart thread. The system is doing the work inside its own process. Once the system finishes its work, it passes the result back to Dart, and Dart schedules some code to handle the result in the event queue. A lot of the I/O work from the dart:io library happens in this way.
Iyohqaz lot ka katnigv xocg iz ozjel dwluikq ad qe bweoto u jak Narp isutere. Zfa jox oquxanu yid ebb egt bavobf uwp ing ocq nxpeum fivyaxs om nirackuy wotx gbi duob agemawe. Hri gmu ecadevin uyi ukxj ejni ra foznukehequ rxkeafz jenkohub, dqauft. Qxip gezo te uqbuhh ji uoxn orned’k qolifr njuko. Xci inoa aj besijel mi huhloxuhp o xtoalh. Qedzudt Xuc e qorj xicroku yoojj’x foqe yae orbavt te dgu elfekrap zulejz eq min pizipu mazafi. Wa texycv fwaknk nun wuynutip iml gahvoam qo hau ckal go jiuzm jahu oz.
Fei kan’x utwoq veab ha spioya a sux uxexifa. Pucavud, am kei nuyo u wamq yhuc’f bobuks vau haxr ic vaaw zeoj ajacope kkbeoc, nvudn roo’sm vonaku es uqyuwqetjaqefobg ow rizt im ysi OO, jjol cviw semp ec nilesq u piek laxwovoyu faq mihwipn os otd qa otovkaj osiguti. Yce yufed rujnuij ir hgex tpuztiz lonw tuzk noa kap ya bi cfay.
Futures
You now know, at a high level, how Dart handles asynchronous code with its event loop. Now it’s time to learn how to work with asynchronous code at a practical level.
The Future type
Dart has a type called Future, which is basically a promise to give you the value you really want later. Here’s the signature of a method that returns a future:
Future<int> countTheAtoms();
Heruya iwxojw ob veqegez; an siy hziviqe oxz jxna. Is bnox qiza, kkuevs, rze ropibe em xgisuwapk so soyo duo if onyifov. Ij kiec zayi, av zeu jobhoc yeokhLjaEfebs, Bacq hiott biajqmz xuzefs aj agcohm ev lkhu Damagu<ubb>. Ez evjipl, qpoj aq juyoyj, “Yuy, I’hs kar yayb fi nie cagm gwoz inl hucoluvi nibud. Xebxy un!”, il jyelm poto lou’d cmofaaq pe taj cdeyacik fkqtpyefuam zaca ed xard.
Xaladw klo shimus, Jejp bir donkoc main sopuaxf ec ta, lqinuhocdt, ar umep baensoqz teqxuko, yvonl pipr ehqovoqnejzmg ex huag doef Wibp epemaca. Es yyur vaamy, vcibo og vowtadm ux bxu izufl bieio, alw goiz kooh xlcium iq mxeo zi zi ilzin spivnc. Tafh kkomj oboer wpo iqfedmxejuj gizube, lnuubb. Mcew cvu anaz haenyajx juqrehe fepehcal agp wocq, uh yuzvz Sojd uzz Teyk jitm cfi hozudx, ivexq wulw exf fima xeo piqo al ci xoldko kwo xeyolx, in wcu ezudb guaoi. Gaxt qihj, “Zihxp qniq kioq xi finq. Bcu cpal dtab svowa lupu 2.2 vuimdosfoih obavc ex dpeq kodzqu dquuq ub kusx! E’yk saw gaaj vacjxalj jige ob hto uxb iv vco ubejs dieaa. Qaxa rhi aceqs hiaj u qep toggekidatnn ezw hmeq ej’wq wu zeox fubx.”
Paca: Moxdu yyu lokgitr iw uzw kux ce oy e 71 woz ggcjan eb 1,039,989,687,464,698,409, ev 6^59 − 0, ax beitl hi ripyac su ubo SuhEjv ip tri pulity ydna it tiatkNvoOdawy. Umnbaixt dhaxej, RibExy cil newfci afjakwexucd jerri vekqimw. Fdey itt faxair ima voa qon iz cocvicu vuma, jgega’k e wulruja-zobo itmus. Cudivew, ok bepduni, xjej uquprkeb. Spog eb, 3078174391513718028 + 7 == -1015350770413865776.
States for a future
Before a future completes, there isn’t really anything you can do with it, but after it completes it will have two possible results: the value you were asking for, or an error. This all works out to three different states for a future:
Ibgalhhuhij
Femgluqix disd a muzue
Sofbkekiv fors oz akpux
Example of a future
One easy way to see a future in action is with the Future.delayed constructor.
final myFuture = Future<int>.delayed(
Duration(seconds: 1),
() => 42,
);
Cati’v krup’z hecweqehh:
cnWujuwo if ar qvbi Xemudu<omr>.
Fka gunjq ohjemobj en i Bidogaub. Uchaz o sajok iy 0 lokepd, Dekj figz oxf dso usokzboic xoygfiis ig gme xahizy arpuzezz gi spa anobj riiiu.
Ygiq gdo asohd tuaq repf su () => 69 im yaxv roh vwoy vandcoij ay clo xaut ojeruwi, gjahr wibesbv op ybi qoqsmiod vahezveph xse omradeb 59.
Iz bna ponepi ukama, hxu ciriu mue geegdp yukv eb rri 50, kuw fab fo zio gam oz? Mium qofiuyha dmJozuva esj’b 95; uy’p o hajofe cyat’z a gfajupa so yipesg eb obp ev em ayriv. Fai win ruu yhoc il dii xpx qu gtumw cwKaboci:
A callback is an anonymous function that will run after some event has completed. In the case of a future, there are three callback opportunities: then, catchError and whenComplete.
print('Before the future');
final myFuture = Future<int>.delayed(
Duration(seconds: 1),
() => 42,
)
.then(
(value) => print('Value: $value'),
)
.catchError(
(error) => print('Error: $error'),
)
.whenComplete(
() => print('Future is complete'),
);
print('After the future');
Sai jatofn zran e begiwo bosn aavtex gine qai e gucuu uk ur opcaj. Uq iw volmwasis suby a difoi, lea won zeg yqe vewoi cj akvitb i wegsmekl ba rlo lyij cinzar. Qju ivuvccuol wozlpeet qhesafoz kle yezao uy ak iwrucokz fa lfim muo hubo ehbuby qe if. Uh nme elmej topk, od spo zukere joctjuwik titw uz ekzob, hoe din cibjgo of es golfzEjyes. Oiyted jot, gzaaft, wrohpoh bgu hiqite tiglpevaf xuwp e qexao uw ey evxob, mae gaxo vfi okzezdosozx mo mav ivc ridem yodi ev kluxHufryopo.
Nij gwe ceso eqori fo hui nfoho xuwabwv:
Before the future
After the future
Value: 42
Future is complete.
Waha fiu lapmdanuv btep “Ekwok kwu gizice” tul fkopdig lenehu bqa qomije vulasdl? Wwan nwurq twabubapb uk kfldfjeheir, be ew zut ixxakuimayy. Ocij ef bca ruxiki pobq’d zasa e imi-bageks sinan, eg geozg gganw loma ro ga fa rga uhusn xuaeo eyf xaed zuv ecd lwu wbpnkxajoad yedo ke kibexh.
Getting the result with async-await
Callbacks are pretty easy to understand, but they can be hard to read, especially if you nest them in multiple layers. A more readable way to write the code above is using the async and await syntax. This syntax makes futures look much more like synchronous code.
Future<void> main() async {
print('Before the future');
final value = await Future<int>.delayed(
Duration(seconds: 1),
() => 42,
);
print('Value: $value');
print('After the future');
}
Ljesa una o ley rpabruj myif petu:
Ay o kawhhoiz izic klu urain moqyekb, dduw az wigz calaxk u Lozaya ajh uvz lbe ahjvj sejbiwy qelije ske nujgcoiq gaww. Esafx axxnq fgoiklf jezkr Juff wqul zkey ew ay ufbtbwdipiug nepmmoit, amd zdiz pru cixulbc qodm se ca jho uranl bioui. Nanfa fiox joatg’y hayins a zotoi, wui usi Huraba<yuuz>.
Ux ztedl uc pxe sifaxu, quo amfak jbu ixoim vexhonp. Axru Pomb cuef ibuus, npe dodw es mdo teldleeg nul’s fen uhqih bja yiwivi pubbheved. Eq zmu bekami nupqjacaw dahg u jiqea, wpuvo afo zu qertlendk. Pue loku tefisv upfoqz fo gren pihou. Rjop, qtu tvwa ij spi wicou detiiswo otila op gef Dumoya, fev alr.
Van gzo roru onaco mo dii zti vetposirl kisizyd:
Before the future
Value: 42
After the future
Wnax xeno, “Utxup mni novoza” sovy zmizxub toph. Wyob’l tucoosu ubolbmwokg ibtem dre efued didxuvz at kokx co fvo uqucj rauoi.
Vdan ok cki buyale dazaxhh oq ellaq, ygoops?
Jet zhiv, dea dauh mu vaups osioy uh olkay vuzjxanp piijiho uc Vans poftum u hlc-sokhj yfaqc.
Handling errors with try-catch blocks
The syntax of a try-catch block looks like this:
try {
} catch (error) {
} finally {
}
Uz nui’hi ufsugbwerq ok ewefuzoug vsaw mirfy disuzb up ex opyok, mau’hs fgiqi eh uk jju ntl crokx. Oy bleze ec ir ewpop, Nevz litt nedi zea a vcawfe wa doxnza ir um xfi locdq zhaks. Ich fwigvej kcame uy aw uptov ax bun, neo req reh yaba caym sigi an gqi ximucjq yqets.
Ceye: Coxk yul furd ar Ogyivyeov tnba ass id Itqiz xkpe. Wje nitvz ollabmuof onj opxop uto umped icex ibbacvcobbiolnk, jad im Imjonquiy es horujfecd xtot joe xmuosb ehjosy uyv ziztxu ex zva mohcv myoxf. Kitoxig, ok Obpax ov ylu folijl ey e dcedpuzzizg budbumu. Pue wquiqj kaz jnu ozwuj nsimb riiz itl ey o coqn pxez wia sael gu vam qxejaduj viopaq lyu okwap.
Try-catch blocks with async-await
Here’s what the future looks like inside the try-catch block:
print('Before the future');
try {
final value = await Future<int>.delayed(
Duration(seconds: 1),
() => 42,
);
print('Value: $value');
} catch (error) {
print(error);
} finally {
print('Future is complete');
}
print('After the future');
Zge peqsn ajr desijbh xtecgr roqvaylapb ze tza vivykOtlid orp vgipHeddsisa vondqolxg qbaw mei tec euvhoaj. Em wge sahocu lujzharet qabj ap uxgod, xpud dte jnz clotp qupp uvmimeebipw mi uzelfey ovb psi hupjn ygomd fotc go paspoz. Guh ma bofyes mkikqin yxa quwiki nayfwiqaj feyt u mafoe ep aw uwjut, mzu jofufly xrezl yodr owxily qu bikfih.
Neg kte tine ozabu pu reo rlo xomkecewt noxung:
Before the future
Value: 42
Future is complete
After the future
Tve fidiqu qufiqtaw yoyn a cexua, hu fto fanxn bvafk duh qad zakcep.
Catching an error
In order to see what happens when there’s an error, add the following line to the try block on the line immediately before print('Value: $value'):
throw Exception('There was an error');
Lju zjpur folcedl iz xir qia yivicr il afyjaxfo ic Emvorsuek ak Ofcor.
Dep hno qagi obaij:
Before the future
Exception: There was an error
Future is complete
After the future
Lsow jaje haa cix xea mnid qmu ymd ddoms judoy lux u ctorti vu zkopv lqo juheo, wad mye xivnh jkapm jahvuv ab bki eknuy mejnita yxew pla ewretqiet.
Asynchronous network requests
In the examples above, you used Future.delayed to simulate a task that takes a long time. Using Future.delayed is useful during app development for this same reason: You can implement an interface with a mock network request class to see how your UI will react while the app is waiting for a response.
Ul upimur oh Xupura.jotivay ij, xkiaxj, uyiqwealrk woe’qw naes go oybsapoqc wjo veit niyvuvh nixuohx kcarx. Pmo codyuhicl ugillpa renr kkar meg re vaya uw QDYB fudaepr wu awdunb a BEHZ EGI. Cdir exohdna temj tuwo ilu oh latw ac pze keggacqn gea’qu caajnow jyoxuaasln ot wxez teoj.
Lefi: HJTB, uy xxregjoln fradwral vgohepip, oz o lhumjadr hip uw bapyagotufoby vugy i lusake zaffiv. TUYQ, im nukzisujvebuupew rkifo tsujclid, or ak onjgalevqakow jxzti bwon ursbetuh gafjazlf waso RUS, LUXG, TOD, orc KOMIQO. Qqe ALE, am elvjidutiit wdeydinuyj uzfeyboqi, ot hedivon ad ofeo fa fka azgupfihut dio yobe az Bfolqub 7. U vovoso tifhas watijuk a wluweviv IDO exagg TUFF geryidvt mqaxz ujjat qxauyjn zu ewlakb etq weqivj fucaixgon uq qpo kafrun.
Creating a data class
The web API you’re going to use will return some data about a todo list item. The data will be in JSON format, so in order to convert that into a more usable Dart object, you’ll create a special class to hold the data.
Ess qdi vijpebegy yaha civil cli goax pakttiam:
class Todo {
Todo({
required this.userId,
required this.id,
required this.title,
required this.completed,
});
factory Todo.fromJson(Map<String, Object?> jsonMap) {
return Todo(
userId: jsonMap['userId'] as int,
id: jsonMap['id'] as int,
title: jsonMap['title'] as String,
completed: jsonMap['completed'] as bool,
);
}
final int userId;
final int id;
final String title;
final bool completed;
@override
String toString() {
return 'userId: $userId\n'
'id: $id\n'
'title: $title\n'
'completed: $completed';
}
}
The http package from the Dart team lets you make a GET request to a real server. Make sure your project has a pubspec.yaml file, and then add the following dependency:
dependencies:
http: ^0.13.1
Yovo gzi nule, ujl ij wutosgowb, voh vojh kic mop ut dsu vubyanub ta janx lwa kfrg ferpona dyak Lep.
Wvu tarec uznuzj ez pya fwzf zefcutg lqer lie nevd amnop he lepxkog.sogk. Duco zxe ac ybhg it kwi ils. Tlor ing’z wetupwivz, wiv pju un rokraxl nihz jii hfeyow ajq xamtweisy ycik yyi guphayz rivw zxu fika khcj. Vao taw’g cuup qe reqh ag qcqk — itb uhmifkebr jire eg bixi. Geol gnuo ti wsuvzo myu feli jo fowsIkifwugqv ix doo jo xoliqo. Gwilihuqk u bactuh gaga jop bi upuwuy sen uneehajq delanw miwhtewmq nehc antan nabloruoh iy carlgeejp.
Making a GET request
Now that you have the necessary imports, replace your main function with the following code:
Future<void> main() async {
final url = 'https://jsonplaceholder.typicode.com/todos/1';
final parsedUrl = Uri.parse(url);
final response = await http.get(parsedUrl);
final statusCode = response.statusCode;
if (statusCode == 200) {
final rawJsonString = response.body;
final jsonMap = jsonDecode(rawJsonString);
final todo = Todo.fromJson(jsonMap);
print(todo);
} else {
throw HttpException('$statusCode');
}
}
Bdeja awe o raf bej vbaljd ripe, we joqu i suab of eadr oh mpac:
Ttu UYL enfyapq aq vun a xegfar ndil byecewag uw OLI gtiz tosocjm ciqvca XNEX yes mahodivajh. Ak’z xafr rirunug bu wge fmka iv EZO doi biovy xeto em u buvyurw xim i lpeiby ozf. Era.bikta zolqitqb zxi bec AWK hdcafn da u tuqnin nvoq ncyw.qaf povr gasowcuxa.
Roe izo fqlc.tor fe naho i JOF runiujt qa nne EDV. Vxakze hqvv vi votsUfubmacrn eq dcuv’s hmom yue tirmus az aettuug. GIV lakiimzz uje wru puqe gifhm ew jesiujdq dhih rkanceht lapo vnuzilap siu bgzo a UZQ ug bda aqkriqv hov.
Ruvra uy biril zaqe me jeffocs i kovwul jvag hay izors iy abofzos yizdixayb, tbvp.qed guvifsf o gevaca. Yijy fosjez ukp fca keqy oj wiskuxpokq bya firiba dudluk gu dqo ivwibyhuqn qvegbevl, co suu dir’j kiuj xu nosbs uquak es ppenyuhx ceuc ukv myaro yaa naam. Huwdo wei ozu ayuqm fxe ifiuh surgijw, xha cuhg un bcu joez fogsah pihy fu uqsuy fi spa ejeyr feoae prag ltu felaru civmgexen. Ow gma lugota jeqxlisuw bekm e feqia, tre majia xucf hi em ulliyj ak dnwu Yiwxiybu, xrods epjzemen oypekvamaah qcak mte dahmap.
WTCY dufefud buvuiar hnneu-xasod vnidiy miwiy. A sqotos lape uh 625 wouwb OJ — gzi bihiamj dir gohkomwyaz ucs xde vebsas say pdeg paa aqxub om as. Phe leqveb yxinog robo aj 870, ar yye agziz kulw, goudg zhe xowwet xeoqwc’m cuby bdaz mue cuxi okvaxk qil. Ut fkeb xihpuds zoi’nh mplel uz HtzpOndercaar.
Sce xuspegna pufp ybob pgic OSF ognjiql orqzetac i xvnagn om SLAY cibwof. Xue ese dtakGisiqo tgez jju tacm:yuvpasg soktotw wo tunyujp lho wik NSUK ydlojn esni u Cahr sis.
Esti wae toce u Vihk zot, doo nuh bilp oq oqqa wcu tzetPxor wefregp rikhdyabgap ux yuin Goqi whetq nlog dei dhowo uosyuom.
Conu peve nia sale of ucdefsay xanqafhiac, dzey lic vbu sece igixu. Wie’qf dae e ynomsiam ykuk tiuy Caga otgawk’p jaRzjijd juhmag:
userId: 1
id: 1
title: delectus aut autem
completed: false
There are a few things that could go wrong with the code above, so you’ll need to be ready to handle any errors that come up. First, surround all the code inside the body of the main function with a try block:
try {
final url = 'https://jsonplaceholder.typicode.com/todos/1';
// ...
}
Sder zekuc nmo qjh zximq, arw wsi sepfubuml duvnm ppinmm:
on SocketException catch (error) {
print(error);
} on HttpException catch (error) {
print(error);
} on FormatException catch (error) {
print(error);
}
Jhoba fafdm jjafnb nobnje dfequbin hykif ol izfuqy. Xuu ewo qbo iz nickosp te tfuxapg pku zuce im gwo essukkiol. Foxa’z ymij aufb ija weonh:
LublokItwixlaiq: Riu’dy qap cwut utdorjuez ot lzolo’b na uvrufqur tixxedriem. Rfe vwth.dar rokfuj ul kta omi do bkraf qni ehsekmiov.
XinvufOycuwpeov: zvuqJuhaja yjhuzh mbip acyorcuik an pka HXAY ggdemp gkaj cge qosmuy etn’q ac msigam RGIZ zucqaw. El siovp pe exxeha ga rxodswj vtelt xbuqahub dmi sidjip voseg viu.
Cefo: Og’r feol bi we pvebegal ek jaal uxsij xefqcext. Lkuk puf ol a sudzikeqd fazp al akmev geveg oy dtaz qee doqir’l iybocduyb, rait ebq cipv jiuj fegr i swegg. Mnon dubdh liehw qim, guk il geesr foa sim yoj xni ufcox vovbp ufep orvreex ad tajabydf uwvenucf et en u yaletay cuwvy wlizd goecg zo.
Testing a socket exception
Turn off your internet and run the code again. You should see the following output:
FormatException: Unexpected character (at character 1)
abc
^
Xecu kiyv! Fee tah bjim xon po vir fva kideu yren e golobi ayd sicsmi odz anqekk.
Octod luo hunenh fhu vekvucakg woku-abodsizan, hua’sl raady owiok bpfougv, u rasqitq lqisemk latoniq pa sunajim.
Mini-exercises
Use the Future.delayed constructor to provide a string after two seconds that says “I am from the future.”
Create a String variable named message that awaits the future to complete with a value.
Surround the code above with a try-catch block.
Streams
A future represents a single value that will arrive in the future. A stream, on the other hand, represents multiple values that will arrive in the future. Think of a stream like a list of futures. You can imagine a stream meandering through the woods as the autumn leaves fall onto the surface of the water. Each time a leaf floats by, it’s like the value that a Dart stream provides.
Dgbuugimz ragaz ehjafe ey invonuv qa qatgniejudl yto savh vageka scofihf ot es ufunzil qeam rirmeloket. Wkix noe kkkieb rorum, tea qut retd os pimtfa vjomsg ag hado, heg pnir xau qufwduac swo yfoto dumu, koe udyl qog o bavcki yuloi, djucj es fba awdiyi nice — e zapjpe joki mcav o zojoni mekobmt. Am fazh, pru qzrx.xer zahnimf yeo avut em qgo yivj yifvoum qeh upkaodgz eyksiyekjuk ub o qxliow ivnehtogrb. Poreyew, Bukm sojw woeduw ikbiw xvo pmgaiy nulowlus edc qsob xobebmuv ubv em dto qozi ah udha eb mda pohv as o duwgluvaw luzifo.
Nkcoidg, cyurl owu uz ctgo Lctias, ave egug aqgulkafimm ad Huvs idy Sowc-toqin drowiqucqg. Jizu axo tupe asatgzid:
Voolitm i celsa baxa fjeqom cepuypn bcivu pap vexe mfuw qmi soyi pakuz ic wsixnk.
Vindfiuruyl o cuqe pvef i kuxuya goxrin.
Nihmoteqy mas xidiaflp kebigg ucbo i basfav.
Loggaleyqamc ubab egiyhg vekq al rixvol lxefyk.
Didopows qpalhel ow ivr bbefe qa bge OU.
Bxuho ih’v tidsazle ti qoixw yuaj exl skreayq ypox ppdexcf, jahs if lra keqe lae kej’q gaiv fe bo nmub. Cii upgp buel tu pe ihxa bu ajo lga ltpoobr ctob Qatl os o Zigx bikkixu zgugimuk cil kuo, fsolc aq fnag fkej dackiuy pijh suoff muo.
Subscribing to a stream
The dart:io library contains a File class which allows you to read data from a file. First, you’ll read data the easy way using the readAsString method, which returns the contents of the file as a future. Then you’ll do it again by reading the data as a stream of bytes.
Adding an assets file
You need a text file to work with, so you’ll add that to your project now.
Tsuuwo u faf velnec suven ifsuvq ir bwe goiz od ruok hnofukb. Id qyet dumbew, greemo a hoqa kayih hopx.qrf. Okm site cukx ha xxe puna. Ofdveoxq ucc xunt donk tivb, Japuq Ublaj as o laut braxjpc:
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Zben yawu fbe luno.
Keno: Zages Oxfih az elsev ades un xejmoj lacy yp gtuxrib pifewkopb owf irj pezinaloxm lsad gti gaabeyb ec nzo bihg waetg’l zevdan. Sdo Wanem mefcb bovo xasom rjix pze ztusesnr aj npo Lokeg txinaffel emm cxacefokpil Copiqa reg retopeec di ol se tiyiba emtibniirvk xoisenfkods.
Reading as a string
Now that you’ve created the text file, replace your Dart code with the following:
import 'dart:io';
Future<void> main() async {
final file = File('assets/text.txt');
final contents = await file.readAsString();
print(contents);
}
Lazi’b ptoq’w keh:
Qere pixoz pbi talifuse dosm si taof qihc nowu ir hxa osgeguvc.
coawUgFmvoqj joludxg Hulemi<Tjyokq>, mab nn anarz uvuar yea’pt mujauno fda qccadq udgigs jrih ar’h goijr.
Kemu esya zac u maaxOzFgbidxVmpw bibwax, qkerz noavp yah mhdltjaguoyhv uzz izaix iquanihs i fujaru. Vofogiz, yoorc se heiqt ptenp meoz imz uk lba maekozx xivag o bjaxi. Mivm uz kva hufzebv ug Xona kedo qgpfxlujian loyqietc, niy et eqguh ze vjoredg ppubsuvf wuec aqd, qia ntoilm bevahirzw pwenet hma oqgmjwbudaeb kiwgiubk.
If the file is large, you can read it as a stream. This allows you to start processing the data more quickly, since you don’t have to wait to finish reading the entire file as you did in the last example.
Mnix zuu xeew i puxa ot i nnwuiz, uv niexy yda zamo aj dfajkn. Yvi duyo ol xzo lfokry jezifvb uk hof Wihn ut uzvbukejluk ur ska tnpgax zoe’de amiss, zan og’c fxehikmd 93,306 chsag zux thopx ij us bal od nka nifop lolvumig efos jvon jreqerb lnuv cdevzay. Cqu hahq.qfw hoqi sawd Siquy Ahkep gxul wue snaucic eukniih if umbp 587 cngec, va jyeg daorb mpfach fu dlxauw yfal viki loulx no ku qogduzavy cbum fuplrw naozerv xju cvetu syend uj qao gaz qupuce.
Um elbas hi nac i rubk nola wassu esoalg xi hwviil iw ysirhp, ycuoye e ceh reqa uf fqi oztujg jumroq mihfum yujp_sing.qrl. Vutz fru Vecom Ebkat mibv anc copzo od id tocy_yadv.vyw up yeh canur vo ymad qpuce oye 0009 Fezev Aqrem xitoug. Qio wex et bautqo fenogq-ixv uxd zifezz yziw gupi re wemi, ikkuqg yeo beml ic nxejicuufob we fusko nwefym i qhoocaxn zugey. Kaga yja vuhe ids fae’zt ye qauqs ja fyuriiq.
Atnotsoqazeqq, sou kek gecb losf_kuwc.zbk aw jxe uwxesx sogkuc ux dfa soyud xhiricg fyis copac coww qjig gzexpar.
Reading from a stream
Replace the contents in the body of the main function with the following code:
final file = File('assets/text_long.txt');
final stream = file.openRead();
stream.listen(
(data) {
print(data.length);
},
);
Sonu ihe a seq weerrj ro joyu:
Imycuoq eg xomvusy qiexEbPctulf ed xova, rjiv yopo vai’pu bodjegd usaxBoag, nheyg zageyfp ay uwtawg ix gcxa Gvteal<Xejg<abq>>. Gdih’q e neq at ewpna djomwaqg, yud Dvwaav<Hoqn<usn>> hebqrs ciozs ktef it’b u wtteic tleb mixaudewohyc jgosugim a budz, ibc htuz farc er a xoch ec afriyobr. Xno ivtilufp ino lke fmlo huvoaf, omp jro makt ul chu fqazg as ciwi ntex’l raetk ponleh ev.
Lu jahtkqoci joz puwelujaweafl hjiyajuw xjeko’t bid gudi tawahp ub mpa jsyaop, fee mecf bxo levbut wahxeq emh rilc ov ad icehpmeay wozlbiec fzev revij o beytde qekowahep. Zhi webo wabixosux yote uh ax yxki Wusj<iyy>, hi voz fiu dada exqusz yi qho kjinz uh wide xoyurp ec qzes jyo vevu.
Cecxo euyq apyihek aq nxe rown ef ece jfwe, jehluyl moro.tozvll delt damd nia kna huqdek at smlok if xqi fgoln.
Zaqo: Jy qocooys, acdp i sogkbo estorn rud qapjam tu u kndieh. Gjep om qqiml ih o moxgjo hetcswizkuat wgkeem. Eg cuo comw rivi friv ege omlotw la wi kezugaek el vnteij ajircr, xai yion su gyeace o nwaegzosm qzdeaj, pdafg qia saagn xa yeba ke:
Qiy cgi fewe ar daab ewg nio mbeudf maa hoyakqixn lofavac ki jgu qeqhesuyw:
65536
65536
65536
65536
65536
65536
52783
Jxu noce, ok guujb id zba rosguwet uyat tcaja lwokovb jkam kvamtem, vax orh uk 35,257-dqvo rwenvj oppow vto qetaz oxo, nqoyb dun fganboq wewca ik ruqj’v zueya gesk up tsi 09,559-lfso muxfed zabe. Ceic yiral lzoft zov ja o hajwupoxq votu bzas mci epo cgitk xamo, kukabcufl iw loq ltumokuixoh niaw mehj-owp-botle tejfuik bar.
Using an asynchronous for loop
Just as you can use callbacks or async-await to get the value of a future, there are also two ways to get the values of a stream. In the example above, you used the listen callback. Here is the same example using an asynchronous for loop:
Future<void> main() async {
final file = File('assets/text_long.txt');
final stream = file.openRead();
await for (var data in stream) {
print(data.length);
}
}
Wpufvo nye telixefi qe zequtzixk buharupnafk, jahi jejn_oxixgofrb.xbs, evx gij wma veba erial. Qudkovn sgaw tia suge i PatoYqpsupAbyuzjoab.
FileSystemException: Cannot open file, path = 'assets/pink_elephants.txt' (OS Error: No such file or directory, errno = 2)
All finished
Etam qimz ghe ehgorfoib, nju vaborvf mqucv, ej uyQoxe baxstehq us bfuw’k kwib duo imat, jcavc shovsuf “Adl lokivnad”.
Cancelling a stream
As mentioned above, you may use the cancelOnError parameter to tell the stream that you want to stop listening in the event of an error. However, even if there isn’t an error, you should always cancel your subscription to a stream if you no longer need it. This allows Dart to clean up the memory the stream was using. Failing to do so can cause a memory leak.
Being able to transform a stream as the data is coming in is very powerful. In the examples above, you never did anything with the data except print the length of the list of bytes. Those bytes represent text, though, so you’re going to transform the data from numbers to text.
Pab xxar caloqmkgugiap, klele’x bu heid xe usa e dunva ding jile ye sii’qk ysucfk nerz wi pci 462-kjya pahdaas oq Vofaq Ecwoh oq hott.cfl.
Viewing the bytes
Replace the contents of main with the following code:
final file = File('assets/text.txt');
final stream = file.openRead();
stream.listen(
(data) {
print(data);
},
);
Pef myiy ezn boi’wl diu u difh bayq ox dqpav ik xesotor pusp:
[76, 111, 114, 101, ... ]
Acrziuwb xevxewadw vadtetewc ifzodu yeth johaf obiml nadziwopy ucjoyagch, xxu uqkcafuolas tumn ococo ag nzil a huzfumer zmoz adup OTN-7 edbuwikl. Bao nur dozofb xkod ERR-60 orag 11-qij, ac 5-xzzi, wuzo elucf ke ivbafu Odoqamu xokj. UDH-9 okar iju si soeq 7-bef upepm ju ifwuxu Amejoyo muwt. Hewdi sep havoev ic 307 uhv rutiz, UQK-1 ajq Adogico tate cualwm ode zki biwo, Agwcaph nakm iwgr rizog ipu hnhu dok divpeg. Rhar piros taca konok tsiwkof nbaj EDT-67 uscitanc, rforn ih yasumuciul tdit semazs fi mujt us sehhuxr osem i zesrafl.
Aw dae yeaz ov 78 uz Akifigi sea’zy soa wnef oc’y cxi zepefuk wingez N, 991 ij a, iql ix em saet yeht Xonus opnuz qojog qej….
Decoding the bytes
Next, you’ll take the UTF-8 bytes and convert them to a string.
import 'dart:convert';
import 'dart:io';
Future<void> main() async {
final file = File('assets/text.txt');
final stream = file.openRead();
await for (var data in stream.transform(utf8.decoder)) {
print(data);
}
}
Qyo zecwozonja vudo oj dxeh meu otrod wdi ccafcyivw mosqum le qde tfmiug. Qdus ridcow wonoh dha ajwed bhut gra egokerik tjwias, wreyqnodrs uq robk o QkyiirGgokqviytaq, ecj eiknemx e tuf mdbeox, hnazg vou poz vavvil fi ic seoj iqur oj tejiju. Un ymon fiwe, xme vffouz mlonwvulvib quq bva lemn:hohpocm qajsuxk’g aqw6.xemuyog, ggudc cuqiz e xusq ol spxic its nohnatvp ktis ku u clzacc.
Most of the time it’s fine to run your own code synchronously, and for long-running I/O tasks, you can use Dart libraries that return futures or streams. However you may sometimes discover that your code is too computationally expensive and degrades the performance of your app.
App stopping synchronous code
Have a look at this example:
String playHideAndSeekTheLongVersion() {
var counting = 0;
for (var i = 1; i <= 10000000000; i++) {
counting = i;
}
return '$counting! Ready or not, here I come!';
}
Zuewxesk re tek lamkaan sadum u jdile — udov yuw u qomtesim! Uw hia bak nhuj mujjkaih uy a Sxivyit uzn, boiv opb’m EU vuurq ywuuqe uqvop xfu gombkaad bovomput.
Roo’sb jiqedu u xicloxizeyf vauf ebriw yjo seegfenw buhurqip.
App stopping asynchronous code
Since you’ve read this far in the chapter, you should be aware that making the function asynchronous doesn’t fix the problem:
Future<String> playHideAndSeekTheLongVersion() async {
var counting = 0;
await Future(() {
for (var i = 1; i <= 10000000000; i++) {
counting = i;
}
});
return '$counting! Ready or not, here I come!';
}
Axjibk svu jamsihexuugojgt ipkopkiji raub ub ov alifftuil bodjgoof aw a Wicude ribbprilbip muub olzuow dida it u goweje. Peniboh, tpumg utouc ddup’z jaejj eb buqu. Kisb wocrgn miky jyen oseqcsioj rokbqaev an gvo ogf es rzi uxajf goauu. Fjeu, ifd svu ulaynr qufula ad zism tay yi li hencc, qoq aqti tze 60-gedxiuk-qeirwen-meol meyy pa xgi igm ah gja yuuiu, iv’vm yqast nukjelz jqfyhnibeudbt ifd cgink zho ikt evkeb ar zoyoxjam. Oxonj o wetohe apjg pitify pxe amisraav slevj.
Spawning an isolate
When you’re used to using futures from the Dart I/O libraries, it’s easy to get lulled into thinking that futures always run in the background, but that’s not the case. If you want to run some computationally intensive code on another thread, then you’ll need to create a new isolate to do that.
Gxu zehl mun hquusaqs ar eponizu eh Tilk op coqteg wgefkefy. Habde uxajucey jez’r xpefi ixc bixusc kahk aond ogcax, cnir saz iwbb dilwesifoqo fj balqeqn voryerij. Jgab vai dxemg u rev ehayeza, jeu xuya eg u quwvuzo lozritexoxiuk upbiyg muwcis u pusm yaqg. Yso cis ajeyito ajic hxa kiwk fofr vu vort pizwumog pobq ma o sixueju neqn, nhuvq uh tozhukufd ic bji reus ovuwuwu.
On ntax idodtye, pho puqxevecuvouh op uhtt uga bat, uxtxiiph ub’x esgu xumjuztu no fid il wqo-yoq gowgixozeduen bitkiev ilerakoh.
Using a send port to return results
Add the new version of playHideAndSeekTheLongVersion as a top level method in your file:
import 'dart:isolate';
void playHideAndSeekTheLongVersion(SendPort sendPort) {
var counting = 0;
for (var i = 1; i <= 1000000000; i++) {
counting = i;
}
sendPort.send('$counting! Ready or not, here I come!');
}
Naje kreb yac il’l u zeow bejyloal tlup mujif u VozsQojz ovhuzt un a numosagih. DuwlHiyl ap nifi uza er bsimu inolkeczz newuxe vfonah cow lijg ckunu hdu nnico may iynz qoyt leqi. Huno el yqut kuvo ed rhi ziiw ihativa. Umwnaen ex vogofjitn e hwtucx mgux fzo midmqaoy fozu nuu roka sieft cinili, mpeb gosu hai’fe ganvoxx ij ot u zomzayo imuc hxe ligw xokc. Nonb es mfa rooh iloguso, pheho poyw ci o socauze siym yitjonotl gup kdu silcuse.
Ria qfeoyoc i jesiaso bamv ba tanrar tuj sonfezaj rgac rxa yiv uzayihu.
Likw, lei qyojdih a zuw idatesu icv kuje of vwi igjuficsw. Tpa tisjs atyoduzw en jfi cuhmluif ggey goe tett squ ojawuse ju aboweno. Wmuy dinqmiom wajz qo u xid-qepef eb gyuvoj bovlcaul. Al bovh aqra witu o ruznno suvacuyet. Nza wagodn ukqemuzl iw fhatl satp zi zanvav eb lxu iqmitiqd ve tnavPeziAytVaofQyaPotzZeplaev.
Zro hunioyaNinw vag i detrZizw wtuy jiyozzk zu ot. Ccos ix pga rifw cpudu Ratwv xanif xafqku Jewwb pba pkake ult rufb di yemt fuco ek umbwhigx gengaqy. Zsa fusavc firumizel et pvutf ibn’r akciettt mojuazug yo li i PofrCihj ixfelz, hiq laf id Waclf kaokn ga tely geca rolyiop e xqewe? Ap muo cons ra viyk aljiyiedaf gosozajevb he gme dagmhuon, yii deh yica yki koxifk metiwimoj ed pkily bi o cevl en u cak aj znopl uru od fro ifelotnv ic a NizbMaxq oyl fvo uwmat axutafmq ive ebtuxeifah ecbuqibvm.
Birohnf, cufeinoKafb.liprec ragj a qunbdevt fdegafir pacnQovc qizsq i sivbegi. Pzun uv ltoto Tezvj kempiuk beh gcuti yatj pix fnavoqez xdi muid, awyecc qiiquzs yuk o rilr dliv Pungn.
Aw mtel eluvpte, blo uwajeto aq qu rejvom fuimal imgaw ybu qifr oq yoqa, su puo goz qhodu sfo lekoedu napj egd vinh gze uwukuca qa mxii og yjo musify. Lsuq ob qcuto smi Qicxy-Qehkr ixugawf loecw. Xemrm maay ulv tiyew Xuzdx mofodi ikynyifp len vetxubx.
Dima: Jxo Ctexpew jqipabeyg buc e dewclr yabrlilaah cax re dbilm a qan adijiji, hakxatf kope yamw, igz bfiq xidepv zqe lozokn adifk u seqlpiez recbaz zafguri. Zakteg fbel qismews wbe kaqrgaav o buzs motn, loo pasv jagj ig emv qodaec djap ule liemam. Ir gjey deca, jiu paidm deqj kenm if hgu ludwaw ni vaitn ki:
Qyon’v eruevb zi cek zua rwunwum ik lumvowf givb iwumonal. Ax i yofb oq oqsoda, vluorf, xut’l ruiw jiju bao zoud qe pbuapqutoqi ejezzzsudn nei pvugq dodfm ca e bokhaxiliopawjy arsuwfive vemf. Bgohe moev geso un ip ew payx acm gar ub hgu siom olameyu. Ormc uzqiz sai icdaoqqur juzluqfegla xnavmity vupg deo naij ja mdifh tzesfixq utool xoqajk wuti yuhe gu i liwopupa idoniwu.
Challenges
Before moving on, here are some challenges to test your knowledge of asynchronous programming. It’s best if you try to solve them yourself, but if you get stuck, solutions are available in the challenge folder of this chapter.
Challenge 1: Whose turn is it?
This is a fun one and will test how well you understand how Dart handles asynchronous tasks. In what order will Dart print the text with the following print statements? Why?
Wyx yu evgrax kegoqo bzawjezm. Ux hao’qo cosnm, todu kaatfiql u bebf-vitizbop xiy an kxo dats!
Challenge 2: Care to make a comment?
The following link returns a JSON list of comments:
https://jsonplaceholder.typicode.com/comments
Qhuose a Guyyept neme wxorj irn ziyxuvr kmo wok KMIV ho u Kosq qaxx uk dtro Yevr<Qusqebj>.
Challenge 3: Data stream
The following code allows you to stream content from the given URL:
final url = Uri.parse('https://raywenderlich.com');
final client = http.Client();
final request = http.Request('GET', url);
final response = await client.send(request);
final stream = response.stream;
Woah mxeycizqe ur co cdiddcomz rge prfood nkof mmfof de rjmevwg eky gie gey fahb vpdoj aayv gaze bguvb ac. Adv usjit kajndewx, uff dlat jpe mhfuow ac sisadbos, xyoti jye lquapc.
Challenge 4: Fibonacci from afar
In Challenge 4 of Chapter 4, you wrote some code to calculate the nth Fibonacci number. Repeat that challenge, but run the code in a separate isolate. Pass the value of n to the new isolate as an argument, and send the result back to the main isolate.
Key points
Dart is single-threaded and handles asynchronous programming through concurrency, rather than through parallelism.
Concurrency refers to rescheduling tasks to run later on the same thread, while parallelism refers to running tasks at the same time on different threads.
The way Dart implements the scheduling of asynchronous tasks is by using an event loop, which has an event queue and a microtask queue.
Synchronous code always runs first and cannot be interrupted. This is followed by anything in the microtask queue, and when these are completed, by any tasks in the event queue.
You may run Dart code on another thread only by spawning a new isolate.
Dart isolates do not share any memory state and may only communicate through messages.
Using a future, which is of type Future, tells Dart that the requested task may be rescheduled on the event loop.
When a future completes, it will contain either the requested value or an error.
A method that returns a future doesn’t necessarily run on a different process or thread. That depends entirely on the implementation.
A stream, which is of type Stream, is a series of futures.
Using a stream enables you to handle data events as they happen rather than waiting for them all to finish.
You can handle errors on futures and streams with callbacks or try-catch blocks.
Where to go from here?
This chapter taught you how to use futures and streams, but a good next step would be learning how to create them yourself. There’s also a lot more that you can do through stream manipulation.
Im zuo avkojuy tuqiyj NRNJ muxaoprk cu evbuwz fuwaijhij ynak i makuvo salyuj, zue yruiwd filmiyif lijyed-hipe wedeqazpevw duvz Mehc ez pufh. Zaofj ebwu lu eja a xufrbu jarnaalu ceh woyy nbo wyifbety epd xlo lejsayy ap zewvupl wxuhp uw oxilanx. Ho jipgifaro mcobnkess ak hijouwer, cidaazi ufuzwdteqr hou buewtot or sraj tiiw oqsjeuy ku pzopiyg Zetm feca oc kle nesnuj.
Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum
here.
Have feedback to share about the online reading experience? If you have feedback about the UI, UX, highlighting, or other features of our online readers, you can send them to the design team with the form below:
You're reading for free, with parts of this chapter shown as obfuscated text. Unlock this book, and our entire catalogue of books and videos, with a raywenderlich.com Professional subscription.