Описание тега async-await
Несколько языков программирования поддерживают модель асинхронного программирования с использованием совместных подпрограмм, причем async
а также await
ключевые слова.
Поддержка модели была добавлена в C# и VB в VS2012 и Python в 3.5. Предложение для функции в ECMAScript было принято в стадию 1 для ECMAScript 7. Dart 1.9 также добавлена поддержка модели.
C# и Visual Studio
Асинхронное программирование с async
а также await
был представлен в C# 5.0 в Visual Studio 2012. Поддержка этой концепции языка во время выполнения является частью среды выполнения.NET 4.5 / Windows Phone 8 / Windows 8.x Store.
Также можно использовать async/await
и таргетинг на.NET 4.0 / Windows Phone 7.1 / Silverlight 4 / MonoTouch / MonoDroid / Portable Class Libraries, с Visual Studio 2012+ и Microsoft.Bcl.Async
Пакет NuGet, лицензированный для производственного кода.
Надстройка Async CTP для VS2010 SP1 также доступна, но она не подходит для разработки продукта.
Python
Аналогичный синтаксис был введен в Python 3.5 (см. PEP 492 - Coroutines с синтаксисом async и await.
Раньше можно было писать совместные подпрограммы с помощью генераторов; с введениемawait
а также async
совместные подпрограммы были перенесены на родной язык.
Ecmascript
Внедрение обещаний и генераторов в ECMAScript дает возможность резко улучшить модель уровня языка для написания асинхронного кода в ECMAScript.
Аналогичное предложение было сделано в отношении отложенных функций во время обсуждений ES6. Предложение здесь поддерживает те же варианты использования, используя аналогичный или тот же синтаксис, но напрямую опираясь на генераторы и обещания вместо определения настраиваемых механизмов.
Разработка этого предложения происходит по адресу https://github.com/tc39/ecmascript-asyncawait. Пожалуйста, отправляйте проблемы туда. Нетривиальные вклады доступны только членам TC39, но запросы на извлечение мелких проблем приветствуются и приветствуются!
Статус этого предложения
Это предложение было принято на этапе 1 ("Предложение") процесса спецификации ECMAScript 7 в январе 2014 года (обсуждение).
Примеры
Возьмем следующий пример, впервые написанный с использованием Promises. Этот код связывает набор анимаций с элементом, останавливаясь при возникновении исключения в анимации и возвращая значение, созданное последней успешно выполненной анимацией.
function chainAnimationsPromise(elem, animations) {
var ret = null;
var p = currentPromise;
for(var anim in animations) {
p = p.then(function(val) {
ret = val;
return anim(elem);
})
}
return p.catch(function(e) {
/* ignore and keep going */
}).then(function() {
return ret;
});
}
Уже с обещаниями код значительно улучшен по сравнению с прямым стилем обратного вызова, где такой вид циклов и обработки исключений является сложной задачей.
Task.js и подобные библиотеки предлагают способ использования генераторов для дальнейшего упрощения кода, сохраняя тот же смысл:
function chainAnimationsGenerator(elem, animations) {
return spawn(function*() {
var ret = null;
try {
for(var anim of animations) {
ret = yield anim(elem);
}
} catch(e) { /* ignore and keep going */ }
return ret;
});
}
Это заметное улучшение. Все шаблоны обещаний, выходящие за рамки семантического содержания кода, удаляются, а тело внутренней функции представляет намерение пользователя. Однако существует внешний слой шаблона, который включает код в дополнительную функцию генератора и передает его в библиотеку для преобразования в обещание. Этот уровень необходимо повторять в каждой функции, которая использует этот механизм для создания обещания. Это настолько часто встречается в типичном асинхронном коде Javascript, что есть смысл избавиться от необходимости в оставшемся шаблоне.
При использовании асинхронных функций весь оставшийся шаблон удаляется, а в тексте программы остается только семантически значимый код:
async function chainAnimationsAsync(elem, animations) {
var ret = null;
try {
for(var anim of animations) {
ret = await anim(elem);
}
} catch(e) { /* ignore and keep going */ }
return ret;
}
Это морально похоже на генераторы, которые представляют собой функциональную форму, которая создает объект Generator. Эта новая форма асинхронной функции создает объект Promise.
Мелочи
Асинхронность не предполагает многопоточности, async
или await
Ключевые слова не создают никаких потоков волшебным образом.
Ресурсы:
C#
- Люсьен Вишик, серия видео: шесть основных советов по асинхронности
- Стивен Тауб, видео: Асинхронность на основе задач с помощью Async
- Стивен Тауб, видео: Дзен асинхронности: лучшие практики для повышения производительности
- Блог Стивена Туба и Parallel Team - Часто задаваемые вопросы по Async/Await
- Блог Стивена Клири - Async and Await
- Сообщение Стефана Клири - Нет темы
- Блог Эрика Липперта -
async
-отмеченные сообщения - Журнал MSDN - Лучшие практики асинхронного программирования
- Журнал MSDN - все дело в контексте синхронизации
- Журнал MSDN - пауза и игра с ожиданием
- Журнал MSDN - Асинхронная производительность: понимание затрат на асинхронность и ожидание
- MSDN - Спецификация языка C# для асинхронных функций
- MSDN - асинхронный шаблон на основе задач
- MSDN - Технический документ: асинхронность в.NET
- Документы - Асинхронное программирование (C#)
- Документы - Асинхронное программирование с использованием Async и Await (Visual Basic)