[{"data":1,"prerenderedAt":2255},["ShallowReactive",2],{"page-\u002Frust\u002F23-async-await":3},{"id":4,"title":5,"body":6,"description":2248,"extension":2249,"meta":2250,"navigation":566,"path":2251,"seo":2252,"stem":2253,"__hash__":2254},"content\u002Frust\u002F23-async-await.md","23 — Async \u002F Await",{"type":7,"value":8,"toc":2215},"minimark",[9,13,22,27,116,127,132,166,171,175,226,236,240,247,279,325,335,339,444,469,473,599,609,615,623,686,704,714,717,795,800,806,854,857,861,903,907,1013,1024,1030,1033,1129,1139,1143,1295,1312,1316,1330,1443,1449,1454,1457,1509,1512,1519,1682,1702,1706,1716,1720,1731,1735,1788,1804,1808,1816,1857,1860,1866,1904,1913,1919,2023,2026,2030,2146,2150,2175,2179,2208,2211],[10,11,5],"h1",{"id":12},"_23-async-await",[14,15,16,17,21],"p",{},"Async lets you write concurrent code that looks sequential. Rust's async is ",[18,19,20],"strong",{},"zero-cost"," — futures are state machines compiled by the compiler.",[23,24,26],"h2",{"id":25},"async-functions","Async Functions",[28,29,31],"code-wrapper",{"language":30},"rust",[32,33,37],"pre",{"className":34,"code":35,"language":30,"meta":36,"style":36},"language-rust shiki shiki-themes github-light github-dark","async fn fetch(url: &str) -> String {\n    \u002F\u002F ... await something ...\n    String::from(\"data\")\n}\n","",[38,39,40,81,88,110],"code",{"__ignoreMap":36},[41,42,45,49,52,56,60,63,66,69,72,75,78],"span",{"class":43,"line":44},"line",1,[41,46,48],{"class":47},"svdQ7","async",[41,50,51],{"class":47}," fn",[41,53,55],{"class":54},"sIsaT"," fetch",[41,57,59],{"class":58},"ssxIu","(url",[41,61,62],{"class":47},":",[41,64,65],{"class":47}," &",[41,67,68],{"class":54},"str",[41,70,71],{"class":58},") ",[41,73,74],{"class":47},"->",[41,76,77],{"class":54}," String",[41,79,80],{"class":58}," {\n",[41,82,84],{"class":43,"line":83},2,[41,85,87],{"class":86},"sdCPZ","    \u002F\u002F ... await something ...\n",[41,89,91,94,97,100,103,107],{"class":43,"line":90},3,[41,92,93],{"class":54},"    String",[41,95,96],{"class":47},"::",[41,98,99],{"class":54},"from",[41,101,102],{"class":58},"(",[41,104,106],{"class":105},"sJ6F3","\"data\"",[41,108,109],{"class":58},")\n",[41,111,113],{"class":43,"line":112},4,[41,114,115],{"class":58},"}\n",[14,117,118,119,122,123,126],{},"Calling ",[38,120,121],{},"fetch(...)"," returns a ",[18,124,125],{},"future",", not a value. The body doesn't run until the future is polled.",[23,128,130],{"id":129},"await",[38,131,129],{},[28,133,134],{"language":30},[32,135,137],{"className":34,"code":136,"language":30,"meta":36,"style":36},"let s = fetch(\"https:\u002F\u002Fx\").await;\n",[38,138,139],{"__ignoreMap":36},[41,140,141,144,147,150,152,154,157,160,163],{"class":43,"line":44},[41,142,143],{"class":47},"let",[41,145,146],{"class":58}," s ",[41,148,149],{"class":47},"=",[41,151,55],{"class":54},[41,153,102],{"class":58},[41,155,156],{"class":105},"\"https:\u002F\u002Fx\"",[41,158,159],{"class":58},")",[41,161,162],{"class":47},".await",[41,164,165],{"class":58},";\n",[14,167,168,170],{},[38,169,162],{}," yields control to the executor if the future is pending. The current task is suspended and later resumed.",[23,172,174],{"id":173},"async-is-lazy","Async Is Lazy",[28,176,177],{"language":30},[32,178,180],{"className":34,"code":179,"language":30,"meta":36,"style":36},"let f = async { println!(\"hi\"); };\n\u002F\u002F nothing happens yet\nf.await;   \u002F\u002F body runs now\n",[38,181,182,208,213],{"__ignoreMap":36},[41,183,184,186,189,191,194,197,200,202,205],{"class":43,"line":44},[41,185,143],{"class":47},[41,187,188],{"class":58}," f ",[41,190,149],{"class":47},[41,192,193],{"class":47}," async",[41,195,196],{"class":58}," { ",[41,198,199],{"class":54},"println!",[41,201,102],{"class":58},[41,203,204],{"class":105},"\"hi\"",[41,206,207],{"class":58},"); };\n",[41,209,210],{"class":43,"line":83},[41,211,212],{"class":86},"\u002F\u002F nothing happens yet\n",[41,214,215,218,220,223],{"class":43,"line":90},[41,216,217],{"class":58},"f",[41,219,162],{"class":47},[41,221,222],{"class":58},";   ",[41,224,225],{"class":86},"\u002F\u002F body runs now\n",[14,227,228,229,231,232,235],{},"You must ",[38,230,162],{}," (or ",[38,233,234],{},"spawn",") a future for it to make progress.",[23,237,239],{"id":238},"runtimes","Runtimes",[14,241,242,243,246],{},"Rust ships ",[18,244,245],{},"no built-in async runtime"," — you choose one:",[248,249,250,257,263,269],"ul",{},[251,252,253,256],"li",{},[38,254,255],{},"tokio",": most popular, multi-threaded scheduler, mature ecosystem.",[251,258,259,262],{},[38,260,261],{},"async-std",": mirrors std API, single-threaded by default.",[251,264,265,268],{},[38,266,267],{},"smol",": small, simple.",[251,270,271,274,275,278],{},[38,272,273],{},"embassy",": embedded (",[38,276,277],{},"no_std",").",[28,280,281],{"language":30},[32,282,284],{"className":34,"code":283,"language":30,"meta":36,"style":36},"#[tokio::main]\nasync fn main() {\n    println!(\"hello from tokio\");\n}\n",[38,285,286,296,308,321],{"__ignoreMap":36},[41,287,288,291,293],{"class":43,"line":44},[41,289,290],{"class":58},"#[tokio",[41,292,96],{"class":47},[41,294,295],{"class":58},"main]\n",[41,297,298,300,302,305],{"class":43,"line":83},[41,299,48],{"class":47},[41,301,51],{"class":47},[41,303,304],{"class":54}," main",[41,306,307],{"class":58},"() {\n",[41,309,310,313,315,318],{"class":43,"line":90},[41,311,312],{"class":54},"    println!",[41,314,102],{"class":58},[41,316,317],{"class":105},"\"hello from tokio\"",[41,319,320],{"class":58},");\n",[41,322,323],{"class":43,"line":112},[41,324,115],{"class":58},[14,326,327,330,331,334],{},[38,328,329],{},"tokio::main"," builds a runtime and runs your async ",[38,332,333],{},"main",".",[23,336,338],{"id":337},"spawning-tasks","Spawning Tasks",[28,340,341],{"language":30},[32,342,344],{"className":34,"code":343,"language":30,"meta":36,"style":36},"#[tokio::main]\nasync fn main() {\n    let h = tokio::spawn(async {\n        5\n    });\n    let n: i32 = h.await.unwrap();\n    println!(\"{n}\");\n}\n",[38,345,346,354,364,387,393,399,427,439],{"__ignoreMap":36},[41,347,348,350,352],{"class":43,"line":44},[41,349,290],{"class":58},[41,351,96],{"class":47},[41,353,295],{"class":58},[41,355,356,358,360,362],{"class":43,"line":83},[41,357,48],{"class":47},[41,359,51],{"class":47},[41,361,304],{"class":54},[41,363,307],{"class":58},[41,365,366,369,372,374,377,379,381,383,385],{"class":43,"line":90},[41,367,368],{"class":47},"    let",[41,370,371],{"class":58}," h ",[41,373,149],{"class":47},[41,375,376],{"class":54}," tokio",[41,378,96],{"class":47},[41,380,234],{"class":54},[41,382,102],{"class":58},[41,384,48],{"class":47},[41,386,80],{"class":58},[41,388,389],{"class":43,"line":112},[41,390,392],{"class":391},"snvgF","        5\n",[41,394,396],{"class":43,"line":395},5,[41,397,398],{"class":58},"    });\n",[41,400,402,404,407,409,412,415,418,421,424],{"class":43,"line":401},6,[41,403,368],{"class":47},[41,405,406],{"class":58}," n",[41,408,62],{"class":47},[41,410,411],{"class":54}," i32",[41,413,414],{"class":47}," =",[41,416,417],{"class":58}," h",[41,419,420],{"class":47},".await.",[41,422,423],{"class":54},"unwrap",[41,425,426],{"class":58},"();\n",[41,428,430,432,434,437],{"class":43,"line":429},7,[41,431,312],{"class":54},[41,433,102],{"class":58},[41,435,436],{"class":105},"\"{n}\"",[41,438,320],{"class":58},[41,440,442],{"class":43,"line":441},8,[41,443,115],{"class":58},[248,445,446,454,460],{},[251,447,448,122,451,334],{},[38,449,450],{},"tokio::spawn",[38,452,453],{},"JoinHandle\u003CT>",[251,455,456,457,334],{},"Spawned tasks must be ",[38,458,459],{},"Send + 'static",[251,461,462,464,465,468],{},[38,463,162],{}," on the handle gives ",[38,466,467],{},"Result\u003CT, JoinError>"," (panic propagates).",[23,470,472],{"id":471},"futures","Futures",[28,474,475],{"language":30},[32,476,478],{"className":34,"code":477,"language":30,"meta":36,"style":36},"trait Future {\n    type Output;\n    fn poll(self: Pin\u003C&mut Self>, cx: &mut Context) -> Poll\u003CSelf::Output>;\n}\n\nenum Poll\u003CT> { Ready(T), Pending }\n",[38,479,480,490,500,558,562,568],{"__ignoreMap":36},[41,481,482,485,488],{"class":43,"line":44},[41,483,484],{"class":47},"trait",[41,486,487],{"class":54}," Future",[41,489,80],{"class":58},[41,491,492,495,498],{"class":43,"line":83},[41,493,494],{"class":47},"    type",[41,496,497],{"class":54}," Output",[41,499,165],{"class":58},[41,501,502,505,508,510,513,515,518,521,524,527,530,532,535,538,540,542,545,547,550,552,555],{"class":43,"line":90},[41,503,504],{"class":47},"    fn",[41,506,507],{"class":54}," poll",[41,509,102],{"class":58},[41,511,512],{"class":391},"self",[41,514,62],{"class":47},[41,516,517],{"class":54}," Pin",[41,519,520],{"class":58},"\u003C",[41,522,523],{"class":47},"&mut",[41,525,526],{"class":391}," Self",[41,528,529],{"class":58},">, cx",[41,531,62],{"class":47},[41,533,534],{"class":47}," &mut",[41,536,537],{"class":54}," Context",[41,539,71],{"class":58},[41,541,74],{"class":47},[41,543,544],{"class":54}," Poll",[41,546,520],{"class":58},[41,548,549],{"class":391},"Self",[41,551,96],{"class":47},[41,553,554],{"class":54},"Output",[41,556,557],{"class":58},">;\n",[41,559,560],{"class":43,"line":112},[41,561,115],{"class":58},[41,563,564],{"class":43,"line":395},[41,565,567],{"emptyLinePlaceholder":566},true,"\n",[41,569,570,573,575,577,580,583,586,588,590,593,596],{"class":43,"line":401},[41,571,572],{"class":47},"enum",[41,574,544],{"class":54},[41,576,520],{"class":58},[41,578,579],{"class":54},"T",[41,581,582],{"class":58},"> { ",[41,584,585],{"class":54},"Ready",[41,587,102],{"class":58},[41,589,579],{"class":54},[41,591,592],{"class":58},"), ",[41,594,595],{"class":54},"Pending",[41,597,598],{"class":58}," }\n",[14,600,601,602,605,606,608],{},"You rarely implement ",[38,603,604],{},"Future"," manually. Async functions desugar to anonymous ",[38,607,604],{},"-implementing state machines.",[23,610,612],{"id":611},"pin",[38,613,614],{},"Pin",[14,616,617,619,620,622],{},[38,618,614],{}," guarantees a value won't be moved in memory. Required because self-referential futures (which reference their own stack across ",[38,621,162],{},") would break if moved.",[28,624,625],{"language":30},[32,626,628],{"className":34,"code":627,"language":30,"meta":36,"style":36},"let mut fut = async { 5 };\nlet pinned: Pin\u003C&mut _> = Pin::new(&mut fut);\n",[38,629,630,652],{"__ignoreMap":36},[41,631,632,634,637,640,642,644,646,649],{"class":43,"line":44},[41,633,143],{"class":47},[41,635,636],{"class":47}," mut",[41,638,639],{"class":58}," fut ",[41,641,149],{"class":47},[41,643,193],{"class":47},[41,645,196],{"class":58},[41,647,648],{"class":391},"5",[41,650,651],{"class":58}," };\n",[41,653,654,656,659,661,663,665,667,670,672,674,676,679,681,683],{"class":43,"line":83},[41,655,143],{"class":47},[41,657,658],{"class":58}," pinned",[41,660,62],{"class":47},[41,662,517],{"class":54},[41,664,520],{"class":58},[41,666,523],{"class":47},[41,668,669],{"class":58}," _> ",[41,671,149],{"class":47},[41,673,517],{"class":54},[41,675,96],{"class":47},[41,677,678],{"class":54},"new",[41,680,102],{"class":58},[41,682,523],{"class":47},[41,684,685],{"class":58}," fut);\n",[14,687,688,689,691,692,695,696,699,700,703],{},"You mostly encounter ",[38,690,614],{}," in trait signatures and APIs (e.g., ",[38,693,694],{},"Future::poll","). The ",[38,697,698],{},"pin-utils"," or ",[38,701,702],{},"Box::pin"," handle the common cases.",[23,705,707,710,711],{"id":706},"boxdyn-future-and-pinboxdyn-future",[38,708,709],{},"Box\u003Cdyn Future>"," and ",[38,712,713],{},"Pin\u003CBox\u003Cdyn Future>>",[14,715,716],{},"Because futures have unique unnameable types, storing them in collections or returning them generically requires boxing:",[28,718,719],{"language":30},[32,720,722],{"className":34,"code":721,"language":30,"meta":36,"style":36},"fn make_fut() -> Pin\u003CBox\u003Cdyn Future\u003COutput = i32> + Send>> {\n    Box::pin(async { 5 })\n}\n",[38,723,724,771,791],{"__ignoreMap":36},[41,725,726,729,732,735,737,739,741,744,746,749,751,753,755,757,759,762,765,768],{"class":43,"line":44},[41,727,728],{"class":47},"fn",[41,730,731],{"class":54}," make_fut",[41,733,734],{"class":58},"() ",[41,736,74],{"class":47},[41,738,517],{"class":54},[41,740,520],{"class":58},[41,742,743],{"class":54},"Box",[41,745,520],{"class":58},[41,747,748],{"class":47},"dyn",[41,750,487],{"class":54},[41,752,520],{"class":58},[41,754,554],{"class":54},[41,756,414],{"class":47},[41,758,411],{"class":54},[41,760,761],{"class":58},"> ",[41,763,764],{"class":47},"+",[41,766,767],{"class":54}," Send",[41,769,770],{"class":58},">> {\n",[41,772,773,776,778,780,782,784,786,788],{"class":43,"line":83},[41,774,775],{"class":54},"    Box",[41,777,96],{"class":47},[41,779,611],{"class":54},[41,781,102],{"class":58},[41,783,48],{"class":47},[41,785,196],{"class":58},[41,787,648],{"class":391},[41,789,790],{"class":58}," })\n",[41,792,793],{"class":43,"line":90},[41,794,115],{"class":58},[14,796,797,799],{},[38,798,713],{}," is the trait-object form of a future.",[23,801,803],{"id":802},"impl-future",[38,804,805],{},"impl Future",[28,807,808],{"language":30},[32,809,811],{"className":34,"code":810,"language":30,"meta":36,"style":36},"fn make_fut() -> impl Future\u003COutput = i32> {\n    async { 5 }\n}\n",[38,812,813,839,850],{"__ignoreMap":36},[41,814,815,817,819,821,823,826,828,830,832,834,836],{"class":43,"line":44},[41,816,728],{"class":47},[41,818,731],{"class":54},[41,820,734],{"class":58},[41,822,74],{"class":47},[41,824,825],{"class":47}," impl",[41,827,487],{"class":54},[41,829,520],{"class":58},[41,831,554],{"class":54},[41,833,414],{"class":47},[41,835,411],{"class":54},[41,837,838],{"class":58},"> {\n",[41,840,841,844,846,848],{"class":43,"line":83},[41,842,843],{"class":47},"    async",[41,845,196],{"class":58},[41,847,648],{"class":391},[41,849,598],{"class":58},[41,851,852],{"class":43,"line":90},[41,853,115],{"class":58},[14,855,856],{},"Returns a concrete future type, hidden. Single type per return site.",[23,858,860],{"id":859},"common-async-crates","Common Async Crates",[248,862,863,868,873,879,885,891,897],{},[251,864,865,867],{},[38,866,255],{}," — runtime, I\u002FO, networking, synchronization.",[251,869,870,872],{},[38,871,471],{}," — combinators, streams, sinks.",[251,874,875,878],{},[38,876,877],{},"async-trait"," — async functions in traits (until native support stabilizes; partial in 1.75+).",[251,880,881,884],{},[38,882,883],{},"reqwest"," — HTTP client.",[251,886,887,890],{},[38,888,889],{},"hyper"," — HTTP server\u002Fclient.",[251,892,893,896],{},[38,894,895],{},"sqlx"," — async DB.",[251,898,899,902],{},[38,900,901],{},"axum"," — web framework (tokio-based).",[23,904,906],{"id":905},"async-io","Async IO",[28,908,909],{"language":30},[32,910,912],{"className":34,"code":911,"language":30,"meta":36,"style":36},"use tokio::fs;\n#[tokio::main]\nasync fn main() -> std::io::Result\u003C()> {\n    let s = fs::read_to_string(\"file.txt\").await?;\n    println!(\"{s}\");\n    Ok(())\n}\n",[38,913,914,926,934,962,990,1001,1009],{"__ignoreMap":36},[41,915,916,919,921,923],{"class":43,"line":44},[41,917,918],{"class":47},"use",[41,920,376],{"class":54},[41,922,96],{"class":47},[41,924,925],{"class":58},"fs;\n",[41,927,928,930,932],{"class":43,"line":83},[41,929,290],{"class":58},[41,931,96],{"class":47},[41,933,295],{"class":58},[41,935,936,938,940,942,944,946,949,951,954,956,959],{"class":43,"line":90},[41,937,48],{"class":47},[41,939,51],{"class":47},[41,941,304],{"class":54},[41,943,734],{"class":58},[41,945,74],{"class":47},[41,947,948],{"class":54}," std",[41,950,96],{"class":47},[41,952,953],{"class":54},"io",[41,955,96],{"class":47},[41,957,958],{"class":54},"Result",[41,960,961],{"class":58},"\u003C()> {\n",[41,963,964,966,968,970,973,975,978,980,983,985,988],{"class":43,"line":112},[41,965,368],{"class":47},[41,967,146],{"class":58},[41,969,149],{"class":47},[41,971,972],{"class":54}," fs",[41,974,96],{"class":47},[41,976,977],{"class":54},"read_to_string",[41,979,102],{"class":58},[41,981,982],{"class":105},"\"file.txt\"",[41,984,159],{"class":58},[41,986,987],{"class":47},".await?",[41,989,165],{"class":58},[41,991,992,994,996,999],{"class":43,"line":395},[41,993,312],{"class":54},[41,995,102],{"class":58},[41,997,998],{"class":105},"\"{s}\"",[41,1000,320],{"class":58},[41,1002,1003,1006],{"class":43,"line":401},[41,1004,1005],{"class":54},"    Ok",[41,1007,1008],{"class":58},"(())\n",[41,1010,1011],{"class":43,"line":429},[41,1012,115],{"class":58},[14,1014,1015,1016,1019,1020,1023],{},"Async ",[38,1017,1018],{},"read","\u002F",[38,1021,1022],{},"write"," yield when the syscall would block. The runtime parks the task and wakes it when the OS signals readiness.",[23,1025,1027],{"id":1026},"tokioselect",[38,1028,1029],{},"tokio::select!",[14,1031,1032],{},"Race multiple futures, take the first to complete:",[28,1034,1035],{"language":30},[32,1036,1038],{"className":34,"code":1037,"language":30,"meta":36,"style":36},"tokio::select! {\n    v = first_future() => println!(\"first: {v}\"),\n    _ = tokio::time::sleep(Duration::from_secs(1)) => println!(\"timeout\"),\n}\n",[38,1039,1040,1051,1077,1125],{"__ignoreMap":36},[41,1041,1042,1044,1046,1049],{"class":43,"line":44},[41,1043,255],{"class":54},[41,1045,96],{"class":47},[41,1047,1048],{"class":54},"select!",[41,1050,80],{"class":58},[41,1052,1053,1056,1058,1061,1063,1066,1069,1071,1074],{"class":43,"line":83},[41,1054,1055],{"class":58},"    v ",[41,1057,149],{"class":47},[41,1059,1060],{"class":54}," first_future",[41,1062,734],{"class":58},[41,1064,1065],{"class":47},"=>",[41,1067,1068],{"class":54}," println!",[41,1070,102],{"class":58},[41,1072,1073],{"class":105},"\"first: {v}\"",[41,1075,1076],{"class":58},"),\n",[41,1078,1079,1082,1084,1086,1088,1091,1093,1096,1098,1101,1103,1106,1108,1111,1114,1116,1118,1120,1123],{"class":43,"line":90},[41,1080,1081],{"class":58},"    _ ",[41,1083,149],{"class":47},[41,1085,376],{"class":54},[41,1087,96],{"class":47},[41,1089,1090],{"class":54},"time",[41,1092,96],{"class":47},[41,1094,1095],{"class":54},"sleep",[41,1097,102],{"class":58},[41,1099,1100],{"class":54},"Duration",[41,1102,96],{"class":47},[41,1104,1105],{"class":54},"from_secs",[41,1107,102],{"class":58},[41,1109,1110],{"class":391},"1",[41,1112,1113],{"class":58},")) ",[41,1115,1065],{"class":47},[41,1117,1068],{"class":54},[41,1119,102],{"class":58},[41,1121,1122],{"class":105},"\"timeout\"",[41,1124,1076],{"class":58},[41,1126,1127],{"class":43,"line":112},[41,1128,115],{"class":58},[14,1130,1131,1132,1135,1136,1138],{},"Unselected branches are dropped. Use ",[38,1133,1134],{},"biased"," for ordering, or branch with ",[38,1137,523],{}," futures to reuse them.",[23,1140,1142],{"id":1141},"streams-async-iterators","Streams (Async Iterators)",[28,1144,1145],{"language":30},[32,1146,1148],{"className":34,"code":1147,"language":30,"meta":36,"style":36},"use futures::stream::{self, StreamExt};\n\nlet mut s = stream::iter(vec![1, 2, 3]).map(|x| x * 2);\nwhile let Some(v) = s.next().await {\n    println!(\"{v}\");\n}\n",[38,1149,1150,1178,1182,1249,1280,1291],{"__ignoreMap":36},[41,1151,1152,1154,1157,1159,1162,1164,1167,1169,1172,1175],{"class":43,"line":44},[41,1153,918],{"class":47},[41,1155,1156],{"class":54}," futures",[41,1158,96],{"class":47},[41,1160,1161],{"class":54},"stream",[41,1163,96],{"class":47},[41,1165,1166],{"class":58},"{",[41,1168,512],{"class":391},[41,1170,1171],{"class":58},", ",[41,1173,1174],{"class":54},"StreamExt",[41,1176,1177],{"class":58},"};\n",[41,1179,1180],{"class":43,"line":83},[41,1181,567],{"emptyLinePlaceholder":566},[41,1183,1184,1186,1188,1190,1192,1195,1197,1200,1202,1205,1208,1210,1212,1215,1217,1220,1223,1225,1228,1230,1233,1236,1238,1241,1244,1247],{"class":43,"line":90},[41,1185,143],{"class":47},[41,1187,636],{"class":47},[41,1189,146],{"class":58},[41,1191,149],{"class":47},[41,1193,1194],{"class":54}," stream",[41,1196,96],{"class":47},[41,1198,1199],{"class":54},"iter",[41,1201,102],{"class":58},[41,1203,1204],{"class":54},"vec!",[41,1206,1207],{"class":58},"[",[41,1209,1110],{"class":391},[41,1211,1171],{"class":58},[41,1213,1214],{"class":391},"2",[41,1216,1171],{"class":58},[41,1218,1219],{"class":391},"3",[41,1221,1222],{"class":58},"])",[41,1224,334],{"class":47},[41,1226,1227],{"class":54},"map",[41,1229,102],{"class":58},[41,1231,1232],{"class":47},"|",[41,1234,1235],{"class":58},"x",[41,1237,1232],{"class":47},[41,1239,1240],{"class":58}," x ",[41,1242,1243],{"class":47},"*",[41,1245,1246],{"class":391}," 2",[41,1248,320],{"class":58},[41,1250,1251,1254,1257,1260,1263,1265,1268,1270,1273,1276,1278],{"class":43,"line":112},[41,1252,1253],{"class":47},"while",[41,1255,1256],{"class":47}," let",[41,1258,1259],{"class":54}," Some",[41,1261,1262],{"class":58},"(v) ",[41,1264,149],{"class":47},[41,1266,1267],{"class":58}," s",[41,1269,334],{"class":47},[41,1271,1272],{"class":54},"next",[41,1274,1275],{"class":58},"()",[41,1277,162],{"class":47},[41,1279,80],{"class":58},[41,1281,1282,1284,1286,1289],{"class":43,"line":395},[41,1283,312],{"class":54},[41,1285,102],{"class":58},[41,1287,1288],{"class":105},"\"{v}\"",[41,1290,320],{"class":58},[41,1292,1293],{"class":43,"line":401},[41,1294,115],{"class":58},[14,1296,1297,1300,1301,1304,1305,1019,1308,1311],{},[38,1298,1299],{},"StreamExt::next().await"," is the async equivalent of ",[38,1302,1303],{},"Iterator::next()",". ",[38,1306,1307],{},"try_stream",[38,1309,1310],{},"tokio_stream"," for building streams.",[23,1313,1315],{"id":1314},"channels","Channels",[14,1317,1318,1171,1321,1171,1324,1171,1327,62],{},[38,1319,1320],{},"tokio::sync::mpsc",[38,1322,1323],{},"tokio::sync::broadcast",[38,1325,1326],{},"tokio::sync::oneshot",[38,1328,1329],{},"tokio::sync::watch",[28,1331,1332],{"language":30},[32,1333,1335],{"className":34,"code":1334,"language":30,"meta":36,"style":36},"let (tx, mut rx) = tokio::sync::mpsc::channel(100);\ntokio::spawn(async move {\n    tx.send(5).await.unwrap();\n});\nlet v = rx.recv().await;\n",[38,1336,1337,1376,1393,1415,1420],{"__ignoreMap":36},[41,1338,1339,1341,1344,1347,1350,1352,1354,1356,1359,1361,1364,1366,1369,1371,1374],{"class":43,"line":44},[41,1340,143],{"class":47},[41,1342,1343],{"class":58}," (tx, ",[41,1345,1346],{"class":47},"mut",[41,1348,1349],{"class":58}," rx) ",[41,1351,149],{"class":47},[41,1353,376],{"class":54},[41,1355,96],{"class":47},[41,1357,1358],{"class":54},"sync",[41,1360,96],{"class":47},[41,1362,1363],{"class":54},"mpsc",[41,1365,96],{"class":47},[41,1367,1368],{"class":54},"channel",[41,1370,102],{"class":58},[41,1372,1373],{"class":391},"100",[41,1375,320],{"class":58},[41,1377,1378,1380,1382,1384,1386,1388,1391],{"class":43,"line":83},[41,1379,255],{"class":54},[41,1381,96],{"class":47},[41,1383,234],{"class":54},[41,1385,102],{"class":58},[41,1387,48],{"class":47},[41,1389,1390],{"class":47}," move",[41,1392,80],{"class":58},[41,1394,1395,1398,1400,1403,1405,1407,1409,1411,1413],{"class":43,"line":90},[41,1396,1397],{"class":58},"    tx",[41,1399,334],{"class":47},[41,1401,1402],{"class":54},"send",[41,1404,102],{"class":58},[41,1406,648],{"class":391},[41,1408,159],{"class":58},[41,1410,420],{"class":47},[41,1412,423],{"class":54},[41,1414,426],{"class":58},[41,1416,1417],{"class":43,"line":112},[41,1418,1419],{"class":58},"});\n",[41,1421,1422,1424,1427,1429,1432,1434,1437,1439,1441],{"class":43,"line":395},[41,1423,143],{"class":47},[41,1425,1426],{"class":58}," v ",[41,1428,149],{"class":47},[41,1430,1431],{"class":58}," rx",[41,1433,334],{"class":47},[41,1435,1436],{"class":54},"recv",[41,1438,1275],{"class":58},[41,1440,162],{"class":47},[41,1442,165],{"class":58},[14,1444,1445,1446,1448],{},"Async channels ",[38,1447,162],{}," on send\u002Frecv instead of blocking.",[23,1450,1452],{"id":1451},"spawn_blocking",[38,1453,1451],{},[14,1455,1456],{},"For CPU-bound work or blocking syscalls inside async code:",[28,1458,1459],{"language":30},[32,1460,1462],{"className":34,"code":1461,"language":30,"meta":36,"style":36},"let v = tokio::task::spawn_blocking(|| {\n    cpu_heavy_computation()\n}).await.unwrap();\n",[38,1463,1464,1490,1498],{"__ignoreMap":36},[41,1465,1466,1468,1470,1472,1474,1476,1479,1481,1483,1485,1488],{"class":43,"line":44},[41,1467,143],{"class":47},[41,1469,1426],{"class":58},[41,1471,149],{"class":47},[41,1473,376],{"class":54},[41,1475,96],{"class":47},[41,1477,1478],{"class":54},"task",[41,1480,96],{"class":47},[41,1482,1451],{"class":54},[41,1484,102],{"class":58},[41,1486,1487],{"class":47},"||",[41,1489,80],{"class":58},[41,1491,1492,1495],{"class":43,"line":83},[41,1493,1494],{"class":54},"    cpu_heavy_computation",[41,1496,1497],{"class":58},"()\n",[41,1499,1500,1503,1505,1507],{"class":43,"line":90},[41,1501,1502],{"class":58},"})",[41,1504,420],{"class":47},[41,1506,423],{"class":54},[41,1508,426],{"class":58},[14,1510,1511],{},"Offloads work to a separate thread pool so the async executor isn't blocked.",[23,1513,1515,1516,1518],{"id":1514},"holding-locks-across-await-pitfall","Holding Locks Across ",[38,1517,162],{}," — Pitfall",[28,1520,1521],{"language":30},[32,1522,1524],{"className":34,"code":1523,"language":30,"meta":36,"style":36},"\u002F\u002F BAD: holding std Mutex across await can deadlock \u002F block executor\nlet guard = std_mutex.lock().unwrap();\nsome_async().await;     \u002F\u002F ⚠️ guard held\n\u002F\u002F GOOD:\nlet val = {\n    let g = std_mutex.lock().unwrap();\n    g.clone()\n};\nsome_async(val).await;\n\n\u002F\u002F OR use tokio's async Mutex:\nlet guard = tokio_mutex.lock().await;\nsome_async().await;\n",[38,1525,1526,1531,1556,1571,1576,1587,1610,1622,1626,1638,1643,1649,1671],{"__ignoreMap":36},[41,1527,1528],{"class":43,"line":44},[41,1529,1530],{"class":86},"\u002F\u002F BAD: holding std Mutex across await can deadlock \u002F block executor\n",[41,1532,1533,1535,1538,1540,1543,1545,1548,1550,1552,1554],{"class":43,"line":83},[41,1534,143],{"class":47},[41,1536,1537],{"class":58}," guard ",[41,1539,149],{"class":47},[41,1541,1542],{"class":58}," std_mutex",[41,1544,334],{"class":47},[41,1546,1547],{"class":54},"lock",[41,1549,1275],{"class":58},[41,1551,334],{"class":47},[41,1553,423],{"class":54},[41,1555,426],{"class":58},[41,1557,1558,1561,1563,1565,1568],{"class":43,"line":90},[41,1559,1560],{"class":54},"some_async",[41,1562,1275],{"class":58},[41,1564,162],{"class":47},[41,1566,1567],{"class":58},";     ",[41,1569,1570],{"class":86},"\u002F\u002F ⚠️ guard held\n",[41,1572,1573],{"class":43,"line":112},[41,1574,1575],{"class":86},"\u002F\u002F GOOD:\n",[41,1577,1578,1580,1583,1585],{"class":43,"line":395},[41,1579,143],{"class":47},[41,1581,1582],{"class":58}," val ",[41,1584,149],{"class":47},[41,1586,80],{"class":58},[41,1588,1589,1591,1594,1596,1598,1600,1602,1604,1606,1608],{"class":43,"line":401},[41,1590,368],{"class":47},[41,1592,1593],{"class":58}," g ",[41,1595,149],{"class":47},[41,1597,1542],{"class":58},[41,1599,334],{"class":47},[41,1601,1547],{"class":54},[41,1603,1275],{"class":58},[41,1605,334],{"class":47},[41,1607,423],{"class":54},[41,1609,426],{"class":58},[41,1611,1612,1615,1617,1620],{"class":43,"line":429},[41,1613,1614],{"class":58},"    g",[41,1616,334],{"class":47},[41,1618,1619],{"class":54},"clone",[41,1621,1497],{"class":58},[41,1623,1624],{"class":43,"line":441},[41,1625,1177],{"class":58},[41,1627,1629,1631,1634,1636],{"class":43,"line":1628},9,[41,1630,1560],{"class":54},[41,1632,1633],{"class":58},"(val)",[41,1635,162],{"class":47},[41,1637,165],{"class":58},[41,1639,1641],{"class":43,"line":1640},10,[41,1642,567],{"emptyLinePlaceholder":566},[41,1644,1646],{"class":43,"line":1645},11,[41,1647,1648],{"class":86},"\u002F\u002F OR use tokio's async Mutex:\n",[41,1650,1652,1654,1656,1658,1661,1663,1665,1667,1669],{"class":43,"line":1651},12,[41,1653,143],{"class":47},[41,1655,1537],{"class":58},[41,1657,149],{"class":47},[41,1659,1660],{"class":58}," tokio_mutex",[41,1662,334],{"class":47},[41,1664,1547],{"class":54},[41,1666,1275],{"class":58},[41,1668,162],{"class":47},[41,1670,165],{"class":58},[41,1672,1674,1676,1678,1680],{"class":43,"line":1673},13,[41,1675,1560],{"class":54},[41,1677,1275],{"class":58},[41,1679,162],{"class":47},[41,1681,165],{"class":58},[14,1683,1684,1687,1688,1692,1693,1695,1696,1698,1699,334],{},[38,1685,1686],{},"std::sync::Mutex"," is fine ",[1689,1690,1691],"em",{},"within"," an async function if released before ",[38,1694,162],{},". For locks held across ",[38,1697,162],{},", use ",[38,1700,1701],{},"tokio::sync::Mutex",[23,1703,1705],{"id":1704},"canceling-futures","Canceling Futures",[14,1707,1708,1709,1711,1712,1715],{},"Dropping a future cancels it. The ",[38,1710,1048],{}," drop semantics mean unselected branches are canceled. Use ",[38,1713,1714],{},"CancellationToken"," for cooperative cancellation.",[23,1717,1719],{"id":1718},"backpressure","Backpressure",[14,1721,1722,1723,1726,1727,1730],{},"Use bounded channels (",[38,1724,1725],{},"mpsc::channel(n)","). ",[38,1728,1729],{},".send().await"," blocks when full, naturally propagating backpressure to producers.",[23,1732,1734],{"id":1733},"async-traits-175","Async Traits (1.75+)",[28,1736,1737],{"language":30},[32,1738,1740],{"className":34,"code":1739,"language":30,"meta":36,"style":36},"trait Service {\n    async fn call(&self, req: Request) -> Response;\n}\n",[38,1741,1742,1751,1784],{"__ignoreMap":36},[41,1743,1744,1746,1749],{"class":43,"line":44},[41,1745,484],{"class":47},[41,1747,1748],{"class":54}," Service",[41,1750,80],{"class":58},[41,1752,1753,1755,1757,1760,1762,1765,1767,1770,1772,1775,1777,1779,1782],{"class":43,"line":83},[41,1754,843],{"class":47},[41,1756,51],{"class":47},[41,1758,1759],{"class":54}," call",[41,1761,102],{"class":58},[41,1763,1764],{"class":47},"&",[41,1766,512],{"class":391},[41,1768,1769],{"class":58},", req",[41,1771,62],{"class":47},[41,1773,1774],{"class":54}," Request",[41,1776,71],{"class":58},[41,1778,74],{"class":47},[41,1780,1781],{"class":54}," Response",[41,1783,165],{"class":58},[41,1785,1786],{"class":43,"line":90},[41,1787,115],{"class":58},[14,1789,1790,1791,1793,1794,1797,1798,1800,1801,1803],{},"Native async traits stabilized in 1.75 with limitations (no ",[38,1792,748],{}," dispatch without ",[38,1795,1796],{},"#[async_trait]"," crate, no recursion in some cases). For full features including ",[38,1799,748],{},", use the ",[38,1802,877],{}," crate.",[23,1805,1807],{"id":1806},"common-patterns","Common Patterns",[1809,1810,1812,1813],"h3",{"id":1811},"concurrency-with-join","Concurrency with ",[38,1814,1815],{},"join!",[28,1817,1818],{"language":30},[32,1819,1821],{"className":34,"code":1820,"language":30,"meta":36,"style":36},"let (a, b, c) = tokio::join!(fa(), fb(), fc());\n",[38,1822,1823],{"__ignoreMap":36},[41,1824,1825,1827,1830,1832,1834,1836,1838,1840,1843,1846,1849,1851,1854],{"class":43,"line":44},[41,1826,143],{"class":47},[41,1828,1829],{"class":58}," (a, b, c) ",[41,1831,149],{"class":47},[41,1833,376],{"class":54},[41,1835,96],{"class":47},[41,1837,1815],{"class":54},[41,1839,102],{"class":58},[41,1841,1842],{"class":54},"fa",[41,1844,1845],{"class":58},"(), ",[41,1847,1848],{"class":54},"fb",[41,1850,1845],{"class":58},[41,1852,1853],{"class":54},"fc",[41,1855,1856],{"class":58},"());\n",[14,1858,1859],{},"Runs all three concurrently, waits for all, returns a tuple.",[1809,1861,1812,1863],{"id":1862},"concurrency-with-try_join",[38,1864,1865],{},"try_join!",[28,1867,1868],{"language":30},[32,1869,1871],{"className":34,"code":1870,"language":30,"meta":36,"style":36},"let (a, b) = tokio::try_join!(fa(), fb())?;\n",[38,1872,1873],{"__ignoreMap":36},[41,1874,1875,1877,1880,1882,1884,1886,1888,1890,1892,1894,1896,1899,1902],{"class":43,"line":44},[41,1876,143],{"class":47},[41,1878,1879],{"class":58}," (a, b) ",[41,1881,149],{"class":47},[41,1883,376],{"class":54},[41,1885,96],{"class":47},[41,1887,1865],{"class":54},[41,1889,102],{"class":58},[41,1891,1842],{"class":54},[41,1893,1845],{"class":58},[41,1895,1848],{"class":54},[41,1897,1898],{"class":58},"())",[41,1900,1901],{"class":47},"?",[41,1903,165],{"class":58},[14,1905,1906,1907,1909,1910,334],{},"Like ",[38,1908,1815],{}," but short-circuits on ",[38,1911,1912],{},"Err",[1809,1914,1916],{"id":1915},"futuresunordered",[38,1917,1918],{},"FuturesUnordered",[28,1920,1921],{"language":30},[32,1922,1924],{"className":34,"code":1923,"language":30,"meta":36,"style":36},"use futures::stream::FuturesUnordered;\nlet mut futs = FuturesUnordered::new();\nfuts.push(fa());\nfuts.push(fb());\nwhile let Some(r) = futs.next().await { \u002F* ... *\u002F }\n",[38,1925,1926,1942,1962,1978,1992],{"__ignoreMap":36},[41,1927,1928,1930,1932,1934,1936,1938,1940],{"class":43,"line":44},[41,1929,918],{"class":47},[41,1931,1156],{"class":54},[41,1933,96],{"class":47},[41,1935,1161],{"class":54},[41,1937,96],{"class":47},[41,1939,1918],{"class":54},[41,1941,165],{"class":58},[41,1943,1944,1946,1948,1951,1953,1956,1958,1960],{"class":43,"line":83},[41,1945,143],{"class":47},[41,1947,636],{"class":47},[41,1949,1950],{"class":58}," futs ",[41,1952,149],{"class":47},[41,1954,1955],{"class":54}," FuturesUnordered",[41,1957,96],{"class":47},[41,1959,678],{"class":54},[41,1961,426],{"class":58},[41,1963,1964,1967,1969,1972,1974,1976],{"class":43,"line":90},[41,1965,1966],{"class":58},"futs",[41,1968,334],{"class":47},[41,1970,1971],{"class":54},"push",[41,1973,102],{"class":58},[41,1975,1842],{"class":54},[41,1977,1856],{"class":58},[41,1979,1980,1982,1984,1986,1988,1990],{"class":43,"line":112},[41,1981,1966],{"class":58},[41,1983,334],{"class":47},[41,1985,1971],{"class":54},[41,1987,102],{"class":58},[41,1989,1848],{"class":54},[41,1991,1856],{"class":58},[41,1993,1994,1996,1998,2000,2003,2005,2008,2010,2012,2014,2016,2018,2021],{"class":43,"line":395},[41,1995,1253],{"class":47},[41,1997,1256],{"class":47},[41,1999,1259],{"class":54},[41,2001,2002],{"class":58},"(r) ",[41,2004,149],{"class":47},[41,2006,2007],{"class":58}," futs",[41,2009,334],{"class":47},[41,2011,1272],{"class":54},[41,2013,1275],{"class":58},[41,2015,162],{"class":47},[41,2017,196],{"class":58},[41,2019,2020],{"class":86},"\u002F* ... *\u002F",[41,2022,598],{"class":58},[14,2024,2025],{},"Spawn N futures, await results as they complete (unordered).",[23,2027,2029],{"id":2028},"common-pitfalls","Common Pitfalls",[248,2031,2032,2048,2056,2065,2078,2099,2107,2120,2132],{},[251,2033,2034,2043,2044,699,2046,334],{},[18,2035,2036,2038,2039,2042],{},[38,2037,162],{}," in a ",[38,2040,2041],{},"for"," loop over a sync iterator",": fine; just don't accidentally serialize tasks you wanted to run concurrently — use ",[38,2045,1815],{},[38,2047,234],{},[251,2049,2050,2055],{},[18,2051,2052,2053],{},"Forgetting to ",[38,2054,129],{},": the future is created but never runs — silent bug.",[251,2057,2058,2064],{},[18,2059,2060,2063],{},[38,2061,2062],{},"async fn"," in a trait"," still has rough edges; check current support.",[251,2066,2067,2070,2071,710,2074,2077],{},[18,2068,2069],{},"Runtime-locked I\u002FO",": mixing ",[38,2072,2073],{},"tokio::fs",[38,2075,2076],{},"async-std::fs"," is fine functionally but wasteful; pick one runtime's I\u002FO.",[251,2079,2080,2085,2086,2088,2089,2091,2092,2095,2096,2098],{},[18,2081,2082,1156],{},[38,2083,2084],{},"Send",": futures that hold non-",[38,2087,2084],{}," types across ",[38,2090,162],{}," are ",[38,2093,2094],{},"!Send"," and can't be ",[38,2097,450],{},"ed.",[251,2100,2101,2104,2105,334],{},[18,2102,2103],{},"Long-running blocking code in async",": blocks the executor. Use ",[38,2106,1451],{},[251,2108,2109,2115,2116,2119],{},[18,2110,2111,2112,2114],{},"Memory leaks with ",[38,2113,1048],{}," loops",": each iteration may allocate. Use ",[38,2117,2118],{},"pin_mut!"," or pinned variables.",[251,2121,2122,2127,2128,2131],{},[18,2123,2124,2126],{},[38,2125,329],{}," flavor",": ",[38,2129,2130],{},"#[tokio::main(flavor = \"current_thread\")]"," is single-threaded (less overhead). Default is multi-threaded.",[251,2133,2134,2140,2141,2143,2144,334],{},[18,2135,2136,2139],{},[38,2137,2138],{},"Drop"," cancels futures",": a future dropped mid-",[38,2142,129],{}," is silently canceled; resources are cleaned up via ",[38,2145,2138],{},[23,2147,2149],{"id":2148},"when-to-use-async","When to Use Async",[248,2151,2152,2155,2158,2164],{},[251,2153,2154],{},"Many concurrent I\u002FO-bound tasks (HTTP servers, proxies, scrapers).",[251,2156,2157],{},"Latency-sensitive workloads with lots of waiting.",[251,2159,2160,2161,334],{},"Avoid for CPU-bound work — use threads or ",[38,2162,2163],{},"rayon",[251,2165,2166,2167,2169,2170,2172,2173,278],{},"Avoid in ",[38,2168,277],{},"\u002Fembedded unless using a ",[38,2171,277],{},"-friendly runtime (",[38,2174,273],{},[23,2176,2178],{"id":2177},"summary","Summary",[14,2180,2181,2182,2184,2185,2187,2188,2190,2191,2193,2194,1019,2196,2198,2199,2201,2202,2204,2205,2207],{},"Async is lazy (futures are polled); runtimes drive them. ",[38,2183,255],{}," is the dominant runtime. ",[38,2186,129],{}," yields control; ",[38,2189,234],{}," schedules tasks. ",[38,2192,1048],{}," races; ",[38,2195,1815],{},[38,2197,1865],{}," runs concurrently. Use async-aware channels and locks. Beware holding ",[38,2200,1686],{}," across ",[38,2203,162],{},". Use ",[38,2206,1451],{}," for CPU work or blocking calls.",[14,2209,2210],{},"Next: Macros — code that writes code.",[2212,2213,2214],"style",{},"html pre.shiki code .svdQ7, html code.shiki .svdQ7{--shiki-default:#D73A49;--shiki-github-dark:#F97583}html pre.shiki code .sIsaT, html code.shiki .sIsaT{--shiki-default:#6F42C1;--shiki-github-dark:#B392F0}html pre.shiki code .ssxIu, html code.shiki .ssxIu{--shiki-default:#24292E;--shiki-github-dark:#E1E4E8}html pre.shiki code .sdCPZ, html code.shiki .sdCPZ{--shiki-default:#6A737D;--shiki-github-dark:#6A737D}html pre.shiki code .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-dark:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html.github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html pre.shiki code .snvgF, html code.shiki .snvgF{--shiki-default:#005CC5;--shiki-github-dark:#79B8FF}",{"title":36,"searchDepth":83,"depth":83,"links":2216},[2217,2218,2219,2220,2221,2222,2223,2224,2226,2227,2228,2229,2230,2231,2232,2233,2235,2236,2237,2238,2245,2246,2247],{"id":25,"depth":83,"text":26},{"id":129,"depth":83,"text":129},{"id":173,"depth":83,"text":174},{"id":238,"depth":83,"text":239},{"id":337,"depth":83,"text":338},{"id":471,"depth":83,"text":472},{"id":611,"depth":83,"text":614},{"id":706,"depth":83,"text":2225},"Box\u003Cdyn Future> and Pin\u003CBox\u003Cdyn Future>>",{"id":802,"depth":83,"text":805},{"id":859,"depth":83,"text":860},{"id":905,"depth":83,"text":906},{"id":1026,"depth":83,"text":1029},{"id":1141,"depth":83,"text":1142},{"id":1314,"depth":83,"text":1315},{"id":1451,"depth":83,"text":1451},{"id":1514,"depth":83,"text":2234},"Holding Locks Across .await — Pitfall",{"id":1704,"depth":83,"text":1705},{"id":1718,"depth":83,"text":1719},{"id":1733,"depth":83,"text":1734},{"id":1806,"depth":83,"text":1807,"children":2239},[2240,2242,2244],{"id":1811,"depth":90,"text":2241},"Concurrency with join!",{"id":1862,"depth":90,"text":2243},"Concurrency with try_join!",{"id":1915,"depth":90,"text":1918},{"id":2028,"depth":83,"text":2029},{"id":2148,"depth":83,"text":2149},{"id":2177,"depth":83,"text":2178},"Async lets you write concurrent code that looks sequential. Rust's async is zero-cost — futures are state machines compiled by the compiler.","md",{},"\u002Frust\u002F23-async-await",{"title":5,"description":2248},"rust\u002F23-async-await","J1__5FWWKgjbFmpPeiF9YlKBoFH7FdHIc0CbRE-3WSk",1785944093261]