У програмуванні, await — особливість, яка була впроваджена у C# 5.0, , Python 3.5, Hack, Dart, Kotlin 1.1, експериментальному доповненні для Scala, «нічній» збірці Rust, і в нещодавніх версіях JavaScript. Вона дозволяє здійснити виклик асинхронного методу схожим чином, як викликаються звичайні, синхронні методи.
Базові операції
Все, що роблять ключові слова async та await, є коригуванням коду під час компіляції. Для цього використовується клас Task, який зберігає стан операції.
Приклад коду, в якому використовується await:
public async Task<int> FindPageSize(Uri uri) { var data = await new WebClient().DownloadDataTaskAsync(uri); return data.Length; }
Тут завантажується URI та повертається його довжина. Ключове слово «async» вказує компілятору, що можна переорганізувати код всередині методу, щоб дозволити відкладати відмічені виклики й обгортати їхні результати в Task. Результатом функції FindPageSize є об'єкт типу Task<int> — це означає, що функція повертає ціле число, але воно може бути неготовим для використання, щойно керування повернулося з FindPageSize — на нього потрібно «зачекати».
Тому компілятор може скорегувати цей код до такого вигляду:
public Task<int> FindPageSize(Uri uri) { var data_task = new WebClient().DownloadDataTaskAsync(uri); var after_data_task = data_task.ContinueWith((original_task) => { return original_task.Result.Length; }); return after_data_task; }
async у сигнатурі методу дозволяє корегування коду з використанням Task і ContinueWith при кожному використанні await. Компілятор не змінить код, якщо await не використовується (C# видає попередження), а метод не буде асинхронним.
Task можна використовувати незалежно від await. «await» є синтаксичним цукром для спрощення роботи кінцевого користувача. Тобто, при кожному використанні await решта коду, що використовує результат асинхронної функції, обгортається у блок ContinueWith.
Також, в асинхронному методі не обов'язково використовувати await. При виклику асинхронної функції без використання await задача виконуватиметься у фоновому режимі. Змінну типу Task, яку повернула функція, можна використовувати для отримання інформації про стан завдання. Таким чином, можна запустити кілька асинхронних задач одночасно, зберегти їх у списку й отримати результат, передавши його до Task.WhenAll()
. Це дозволяє їм усім виконуватися одночасно, а потім просто очікує на виконання всіх задач. Це може бути набагато ефективніше за очікування завершення кожної з них. Наприклад, виконуючи 10 мережевих запитів, якщо розпочати їх усі одночасно (а не послідовно, використовуючи await), а потім очікувати виклик WhenAll, це може призвести до паралельного виконання всіх мережевих запитів.
В С#
До сьомої версії С# асинхронні методи обов'язково мають повертати void
, Task
, або Task<T>
. Потім цей список поповнився іншими типами на кшталт ValueTask<T>
. Асинхронні методи, які нічого не повертають, призначені для обробників подій. У більшості випадків результат асинхронного методу, який нічого не повертає, рекомендується позначати як Task
, а не void
, так як це сприяє інтуїтивному керуванню виключеннями.
Сигнатуру методів, що використовують await
, треба позначати за допомогою async
. У методах, які повертають змінні типу Task<T>
та позначені асинхронними, має повертатися змінна типу T
, а не Task<T>
. Компілятор обгортає значення в Task<T>
. Також передбачена можливість виклику функцій, які повертають задачу, через await
, навіть якщо вони не позначені асинхронними.
Наведений нижче асинхронний метод, завантажує дані із URL використовуючи await
.
public async Task<int> SumPageSizesAsync(IList<Uri> uris) { int total = 0; foreach (var uri in uris) { statusText.Text = string.Format("Found {0} bytes ...", total); var data = await new WebClient().DownloadDataTaskAsync(uri); total += data.Length; } statusText.Text = string.Format("Found {0} bytes total", total); return total; }
В C++
В C++, await (який називається co_await в C++) був офіційно долучений до стандарту C++20; також компілятори MSVC та Clang вже підтримують co_await.
В JavaScript
Оператор await в JavaScript може використовуватися лише в функції, що відмічена ключовим словом async. Якщо параметр є Promise-ом, виконання async-функції відновиться, коли Promise буде вирішено(resolved). Якщо Promise буде відхилий(rejected) - в цьому випадку буде викинута помилка, яка може бути оброблена з використанням звичайного сценарію виключення JavaScript. Якщо параметр не є Promise-ом, сам параметр буде повернуто негайно.
Багато бібліотек надають повертають Promise-об'єкти, які також можуть використовуватися в очікуванні, якщо вони узгоджуються з специфікацією для власних Promise-об'єктів JavaScript. Проте обіцянки з бібліотеки jQuery не були сумісними з власними Promis-об'єктами на рівні A+ аж до версії jQuery 3.0.
Приклад (взято з цієї статті):
async function createNewDoc() { let response = await db.post({}); // post a new doc return await db.get(response.id); // find by id } async function main() { try { let doc = await createNewDoc(); console.log(doc); } catch (err) { console.log(err); } }()
Примітки
- . GitHub (англійською) . Архів оригіналу за 11 червня 2018. Процитовано 18 квітня 2018.
- . GitHub (англійською) . Архів оригіналу за 16 січня 2018. Процитовано 18 квітня 2018.
- . MSDN (англійською) . Архів оригіналу за 25 липня 2018. Процитовано 18 квітня 2018.
- . Архів оригіналу за 5 червня 2020. Процитовано 9 травня 2020.
- . Архів оригіналу за 2 червня 2017. Процитовано 2 травня 2017.
- . Архів оригіналу за 21 січня 2021. Процитовано 2 травня 2017.
- . Архів оригіналу за 15 листопада 2015. Процитовано 12 листопада 2015.
Вікіпедія, Українська, Україна, книга, книги, бібліотека, стаття, читати, завантажити, безкоштовно, безкоштовно завантажити, mp3, відео, mp4, 3gp, jpg, jpeg, gif, png, малюнок, музика, пісня, фільм, книга, гра, ігри, мобільний, телефон, android, ios, apple, мобільний телефон, samsung, iphone, xiomi, xiaomi, redmi, honor, oppo, nokia, sonya, mi, ПК, web, Інтернет
U programuvanni await osoblivist yaka bula vprovadzhena u C 5 0 C 20 Python 3 5 Hack Dart Kotlin 1 1 eksperimentalnomu dopovnenni dlya Scala nichnij zbirci Rust i v neshodavnih versiyah JavaScript Vona dozvolyaye zdijsniti viklik asinhronnogo metodu shozhim chinom yak viklikayutsya zvichajni sinhronni metodi Bazovi operaciyiVse sho roblyat klyuchovi slova async ta await ye koriguvannyam kodu pid chas kompilyaciyi Dlya cogo vikoristovuyetsya klas Task yakij zberigaye stan operaciyi Priklad kodu v yakomu vikoristovuyetsya await public async Task lt int gt FindPageSize Uri uri var data await new WebClient DownloadDataTaskAsync uri return data Length Tut zavantazhuyetsya URI ta povertayetsya jogo dovzhina Klyuchove slovo async vkazuye kompilyatoru sho mozhna pereorganizuvati kod vseredini metodu shob dozvoliti vidkladati vidmicheni vikliki j obgortati yihni rezultati v Task Rezultatom funkciyi FindPageSize ye ob yekt tipu Task lt int gt ce oznachaye sho funkciya povertaye cile chislo ale vono mozhe buti negotovim dlya vikoristannya shojno keruvannya povernulosya z FindPageSize na nogo potribno zachekati Tomu kompilyator mozhe skoreguvati cej kod do takogo viglyadu public Task lt int gt FindPageSize Uri uri var data task new WebClient DownloadDataTaskAsync uri var after data task data task ContinueWith original task gt return original task Result Length return after data task async u signaturi metodu dozvolyaye koreguvannya kodu z vikoristannyam Task i ContinueWith pri kozhnomu vikoristanni await Kompilyator ne zminit kod yaksho await ne vikoristovuyetsya C vidaye poperedzhennya a metod ne bude asinhronnim Task mozhna vikoristovuvati nezalezhno vid await await ye sintaksichnim cukrom dlya sproshennya roboti kincevogo koristuvacha Tobto pri kozhnomu vikoristanni await reshta kodu sho vikoristovuye rezultat asinhronnoyi funkciyi obgortayetsya u blok ContinueWith Takozh v asinhronnomu metodi ne obov yazkovo vikoristovuvati await Pri vikliku asinhronnoyi funkciyi bez vikoristannya await zadacha vikonuvatimetsya u fonovomu rezhimi Zminnu tipu Task yaku povernula funkciya mozhna vikoristovuvati dlya otrimannya informaciyi pro stan zavdannya Takim chinom mozhna zapustiti kilka asinhronnih zadach odnochasno zberegti yih u spisku j otrimati rezultat peredavshi jogo do Task WhenAll Ce dozvolyaye yim usim vikonuvatisya odnochasno a potim prosto ochikuye na vikonannya vsih zadach Ce mozhe buti nabagato efektivnishe za ochikuvannya zavershennya kozhnoyi z nih Napriklad vikonuyuchi 10 merezhevih zapitiv yaksho rozpochati yih usi odnochasno a ne poslidovno vikoristovuyuchi await a potim ochikuvati viklik WhenAll ce mozhe prizvesti do paralelnogo vikonannya vsih merezhevih zapitiv V S Dokladnishe C Sharp Do somoyi versiyi S asinhronni metodi obov yazkovo mayut povertati void Task abo Task lt T gt Potim cej spisok popovnivsya inshimi tipami na kshtalt ValueTask lt T gt Asinhronni metodi yaki nichogo ne povertayut priznacheni dlya obrobnikiv podij U bilshosti vipadkiv rezultat asinhronnogo metodu yakij nichogo ne povertaye rekomenduyetsya poznachati yak Task a ne void tak yak ce spriyaye intuyitivnomu keruvannyu viklyuchennyami Signaturu metodiv sho vikoristovuyut await treba poznachati za dopomogoyu async U metodah yaki povertayut zminni tipu Task lt T gt ta poznacheni asinhronnimi maye povertatisya zminna tipu T a ne Task lt T gt Kompilyator obgortaye znachennya v Task lt T gt Takozh peredbachena mozhlivist vikliku funkcij yaki povertayut zadachu cherez await navit yaksho voni ne poznacheni asinhronnimi Navedenij nizhche asinhronnij metod zavantazhuye dani iz URL vikoristovuyuchi await public async Task lt int gt SumPageSizesAsync IList lt Uri gt uris int total 0 foreach var uri in uris statusText Text string Format Found 0 bytes total var data await new WebClient DownloadDataTaskAsync uri total data Length statusText Text string Format Found 0 bytes total total return total V C V C await yakij nazivayetsya co await v C buv oficijno doluchenij do standartu C 20 takozh kompilyatori MSVC ta Clang vzhe pidtrimuyut co await V JavaScriptOperator await v JavaScript mozhe vikoristovuvatisya lishe v funkciyi sho vidmichena klyuchovim slovom async Yaksho parametr ye Promise om vikonannya async funkciyi vidnovitsya koli Promise bude virisheno resolved Yaksho Promise bude vidhilij rejected v comu vipadku bude vikinuta pomilka yaka mozhe buti obroblena z vikoristannyam zvichajnogo scenariyu viklyuchennya JavaScript Yaksho parametr ne ye Promise om sam parametr bude povernuto negajno Bagato bibliotek nadayut povertayut Promise ob yekti yaki takozh mozhut vikoristovuvatisya v ochikuvanni yaksho voni uzgodzhuyutsya z specifikaciyeyu dlya vlasnih Promise ob yektiv JavaScript Prote obicyanki z biblioteki jQuery ne buli sumisnimi z vlasnimi Promis ob yektami na rivni A azh do versiyi jQuery 3 0 Priklad vzyato z ciyeyi statti async function createNewDoc let response await db post post a new doc return await db get response id find by id async function main try let doc await createNewDoc console log doc catch err console log err Primitki GitHub anglijskoyu Arhiv originalu za 11 chervnya 2018 Procitovano 18 kvitnya 2018 GitHub anglijskoyu Arhiv originalu za 16 sichnya 2018 Procitovano 18 kvitnya 2018 MSDN anglijskoyu Arhiv originalu za 25 lipnya 2018 Procitovano 18 kvitnya 2018 Arhiv originalu za 5 chervnya 2020 Procitovano 9 travnya 2020 Arhiv originalu za 2 chervnya 2017 Procitovano 2 travnya 2017 Arhiv originalu za 21 sichnya 2021 Procitovano 2 travnya 2017 Arhiv originalu za 15 listopada 2015 Procitovano 12 listopada 2015