Асинхронное программирование JavaScript. Сила $. Отложено для приложения HTML5

  1. Браузер Асинхронные API
  2. Обработка ошибок
  3. Положить его вместе с $ .Deferred
  4. Случаи применения
  5. Заключение

Одним из наиболее важных аспектов построения гладких и отзывчивых приложений HTML5 является синхронизация между всеми различными частями приложения, такими как выборка данных, обработка, анимация и элементы пользовательского интерфейса.

Основное отличие настольного компьютера или собственной среды заключается в том, что браузеры не предоставляют доступ к модели потоков и предоставляют единый поток для всего, что обращается к пользовательскому интерфейсу (например, DOM). Это означает, что вся логика приложения, обращающаяся к элементам пользовательского интерфейса и изменяющая их, всегда находится в одном потоке, поэтому важно сохранять все рабочие блоки приложения как можно меньшими и эффективными, а также использовать любые асинхронные возможности, предлагаемые браузером. возможный.

Браузер Асинхронные API

К счастью, браузеры предоставляют ряд асинхронных API, таких как обычно используемые API-интерфейсы XHR (XMLHttpRequest или 'AJAX'), а также работники IndexedDB, SQLite, HTML5 Web и API-интерфейсы GeoLocation HTML5. Даже некоторые действия, связанные с DOM, отображаются асинхронно, например CSS3-анимация через события transitionEnd.

Браузеры предоставляют асинхронное программирование логике приложения с помощью событий или обратных вызовов. В основанных на событиях асинхронных API разработчики регистрируют обработчик событий для данного объекта (например, HTML-элемент или другие объекты DOM) и затем вызывают действие. Браузер будет выполнять действие, обычно в другом потоке, и при необходимости запускать событие в основном потоке.

Например, код, использующий XHR API, асинхронный API на основе событий, будет выглядеть следующим образом:

// Создаем объект XHR, чтобы выполнить GET для / ресурса данных var xhr = new XMLHttpRequest (); xhr.open ( "GET", "данные", правда); // зарегистрируем обработчик события xhr.addEventListener ('load', function () {if (xhr.status === 200) {alert ("Мы получили данные:" + xhr.response);}}, false) // выполнить работу xhr.send ();

Событие CSS3 transitionEnd - еще один пример асинхронного API на основе событий.

// получить элемент html с идентификатором 'flyingCar' var flyingCarElem = document.getElementById ("flyingCar"); // зарегистрируем обработчик события // ('transitionEnd' для FireFox, 'webkitTransitionEnd' для webkit) flyingCarElem.addEventListener ("transitionEnd", function () {// будет вызван после завершения перехода. alert ("Автомобиль прибыл" ");}); // добавляем класс CSS3, который будет запускать анимацию // Примечание: некоторые браузеры делегируют некоторые переходы в GPU, но // разработчик не заботится об этом. flyingCarElemen.classList.add ( 'makeItFly')

Другие API-интерфейсы браузера, такие как SQLite и HTML5 Geolocation, основаны на обратном вызове, что означает, что разработчик передает функцию в качестве аргумента, который будет вызываться базовой реализацией с соответствующим разрешением.

Например, для геолокации HTML5 код выглядит так:

// вызов и передача функции в обратный вызов, когда закончите. navigator.geolocation.getCurrentPosition (function (position) {alert ('Lat:' + position.coords.latitude + '' + 'Lon:' + position.coords.longitude);});

В этом случае мы просто вызываем метод и передаем функцию, которая будет вызываться с запрошенным результатом. Это позволяет браузеру реализовывать эту функцию синхронно или асинхронно и предоставлять единый API разработчику независимо от деталей реализации.

Помимо встроенных в браузер асинхронных API, хорошо спроектированные приложения должны также предоставлять свои низкоуровневые API в асинхронном режиме, особенно когда они выполняют какой-либо ввод-вывод или вычислительную сложную обработку. Например, API для получения данных должны быть асинхронными и НЕ должны выглядеть так:

// НЕПРАВИЛЬНО: это приведет к зависанию пользовательского интерфейса при получении данных var data = getData (); оповещение («У нас есть данные:» + данные);

Этот дизайн API требует, чтобы getData () блокировался, что приведет к остановке пользовательского интерфейса до тех пор, пока данные не будут получены. Если данные являются локальными в контексте JavaScript, это может не вызывать проблем, однако, если данные необходимо получать из сети или даже локально в хранилище SQLite или индекса, это может оказать существенное влияние на взаимодействие с пользователем.

Правильный дизайн состоит в том, чтобы упреждающе сделать все API приложений, для обработки которых может потребоваться некоторое время, с самого начала асинхронным, так как преобразование синхронного кода приложения в асинхронный может быть сложной задачей.

Например, упрощенный API getData () может выглядеть примерно так:

getData (function (data) {alert ("Мы получили данные:" + данные);});

Хорошая вещь в этом подходе состоит в том, что это заставляет код пользовательского интерфейса приложения быть асинхронно-ориентированным с самого начала и позволяет нижележащим API решать, нужно ли им быть асинхронным или нет на более позднем этапе.

Обратите внимание, что не все API приложения должны или должны быть асинхронными. Практическое правило заключается в том, что любой API, который выполняет любой тип ввода-вывода или интенсивную обработку (все, что может занять более 15 мс), должен быть открыт асинхронно с самого начала, даже если первая реализация является синхронной.

Обработка ошибок

Один из недостатков асинхронного программирования заключается в том, что традиционный способ обработки ошибок типа try / catch больше не работает, так как ошибки обычно происходят в другом потоке. Следовательно, вызываемый должен иметь структурированный способ уведомления вызывающего абонента, когда что-то идет не так во время обработки.

В асинхронном API на основе событий это часто выполняется кодом приложения, запрашивающим событие или объект при получении события. Для асинхронных API на основе обратного вызова рекомендуется использовать второй аргумент, который принимает функцию, которая будет вызываться в случае сбоя, с соответствующей информацией об ошибке в качестве аргумента.

Наш вызов getData будет выглядеть так:

// getData (successFunc, failFunc); getData (function (data) {alert ("Мы получили данные:" + data);}, function (ex) {alert ("упс, возникла проблема:" + ex);});

Положить его вместе с $ .Deferred

Одно ограничение вышеупомянутого подхода обратного вызова состоит в том, что это может стать действительно громоздким, чтобы написать даже умеренно продвинутую логику синхронизации

Например, если вам нужно подождать два асинхронных API, прежде чем выполнять третий, сложность кода может быстро возрасти.

// сначала делаем данные. getData (function (data) {// затем получаем местоположение getLocation (function (location) {alert ("мы получили данные:" + data + "и location:" + location);}, function (ex) {alert (" Ошибка getLocation: "+ ex);});}, функция (ex) {alert (" ошибка getData: "+ ex);});

Вещи могут стать еще более сложными, когда приложению необходимо выполнить один и тот же вызов из нескольких частей приложения, поскольку каждый вызов должен будет выполнять эти многошаговые вызовы или приложение должно будет реализовать собственный механизм кэширования.

К счастью, существует довольно старая модель, называемая Обещаниями (вроде Будущее в Java) и надежная и современная реализация в ядре jQuery под названием $ .Deferred это обеспечивает простое и мощное решение для асинхронного программирования.

Для простоты шаблон Promises определяет, что асинхронный API возвращает объект Promise, который является своего рода «Обещанием, что результат будет разрешен с соответствующими данными». Чтобы получить разрешение, вызывающая сторона получает объект Promise и вызывает done (successFunc (data)), который сообщит объекту Promise вызывать этот successFunc при разрешении «данных».

Итак, приведенный выше пример вызова getData выглядит так:

// получить объект обещания для этого API var dataPromise = getData (); // зарегистрировать функцию для вызова при разрешении данных dataPromise.done (function (data) {alert ("Мы получили данные:" + data);}); // зарегистрируем функцию сбоя dataPromise.fail (function (ex) {alert ("упс, возникла проблема:" + ex);}); // Примечание: у нас может быть столько dataPromise.done (...), сколько мы хотим. dataPromise.done (function (data) {alert («Мы дважды спрашивали, дважды получаем:» + data);});

Здесь мы сначала получаем объект dataPromise, а затем вызываем метод .done, чтобы зарегистрировать функцию, которую мы хотим вызвать, когда данные будут разрешены. Мы также можем вызвать метод .fail для обработки возможного сбоя. Обратите внимание, что у нас может быть столько вызовов .done или .fail, сколько нам нужно, поскольку базовая реализация Promise (код jQuery) будет обрабатывать регистрацию и обратные вызовы.

С этим шаблоном относительно легко реализовать более продвинутый код синхронизации, и jQuery уже предоставляет наиболее распространенный такой код $ .when ,

Например, вложенный обратный вызов getData / getLocation, приведенный выше, может выглядеть примерно так:

// при условии, что оба метода getData и getLocation возвращают свои соответствующие значения Promise. var combPromise = $ .when (getData (), getLocation ()) // будет вызвана, когда оба метода: getData и getLocation разрешают объединениеPromise.done (функция (данные, местоположение) {предупреждение («Мы получили данные:« + dataResult + »и location:« + location);});

И прелесть всего этого в том, что jQuery.Deferred позволяет разработчикам легко реализовать асинхронную функцию. Например, getData может выглядеть примерно так:

function getData () {// 1) создает объект jQuery Deferred, который будет использоваться var deferred = $ .Deferred (); // ---- вызов AJAX ---- // XMLHttpRequest xhr = new XMLHttpRequest (); xhr.open ( "GET", "данные", правда); // зарегистрируем обработчик события xhr.addEventListener ('load', function () {if (xhr.status === 200) {// 3.1) RESOLVE the DEFERRED (это вызовет все отложенное действие done () ...) .resolve (xhr.response); } else {// 3.2) REJECT the DEFERRED (это вызовет все fail () ...) deferred.reject ("Ошибка HTTP:" + xhr.status); }}, false) // выполнить работу xhr.send (); // Примечание: мог и должен был использовать jQuery.ajax. // Примечание: jQuery.ajax возвращает Promise, но всегда полезно обернуть его // семантикой приложения в другой отложенный / Promise // ---- / вызов AJAX ---- // // 2) return обещание этого отложенного возврата deferred.promise (); }

Таким образом, когда вызывается getData (), он сначала создает новый объект jQuery.Deferred (1), а затем возвращает свой Promise (2), чтобы вызывающий мог зарегистрировать свои функции done и fail. Затем, когда вызов XHR возвращается, он либо разрешает отложенный (3.1), либо отклоняет его (3.2). Выполнение deferred.resolve вызовет все функции done (...) и другие функции обещания (например, then и pipe), а вызов deferred.reject вызовет все функции fail ().

Случаи применения

Вот несколько хороших вариантов использования, где Deferred может быть очень полезен:

Доступ к данным. Предоставление API доступа к данным в виде $ .Deferred часто является правильным дизайном. Это очевидно для удаленных данных, поскольку синхронные удаленные вызовы могут полностью испортить взаимодействие с пользователем, но также верно и для локальных данных, поскольку зачастую API более низкого уровня (например, SQLite и IndexedDB) сами по себе являются асинхронными. $ .When и .pipe от Deferred API чрезвычайно эффективны для синхронизации и объединения асинхронных подзапросов.

Анимация пользовательского интерфейса: организация одной или нескольких анимаций с событиями transitionEnd может быть довольно утомительной, особенно когда анимация представляет собой смесь анимации CSS3 и JavaScript (как это часто бывает). Оборачивание функций анимации как Deferred может значительно снизить сложность кода и повысить гибкость. Очень может помочь даже простая универсальная функция-обертка, такая как cssAnimation (className), которая будет возвращать объект Promise, который разрешается на transitionEnd.

Отображение компонентов пользовательского интерфейса: это немного более продвинутое, но в продвинутых инфраструктурах компонентов HTML также следует использовать Deferred. Если не вдаваться в подробности (это будет предметом другого поста), когда приложению необходимо отобразить различные части пользовательского интерфейса, то жизненный цикл этих компонентов, инкапсулированных в Deferred, позволяет лучше контролировать время.

Любой браузерный асинхронный API. В целях нормализации часто рекомендуется переносить вызовы API браузера как отложенные. Это занимает буквально от 4 до 5 строк кода, но значительно упростит любой код приложения. Как показано в приведенном выше псевдокоде getData / getLocation, это позволяет коду приложений иметь одну асинхронную модель для всех типов API (браузеров, спецификаций приложений и составных).

Кэширование: это своего рода побочное преимущество, но может быть очень полезным в некоторых случаях. Поскольку API Promise (например, .done (..) и .fail (..)) можно вызывать до или после выполнения асинхронного вызова, объект Deferred можно использовать как дескриптор кэширования для асинхронного вызова. Например, CacheManager может просто отслеживать Deferred для заданных запросов и возвращать Promise соответствующего Deferred, если он не был аннулирован. Прелесть в том, что вызывающему не нужно знать, был ли вызов уже разрешен или находится в процессе разрешения, его функция обратного вызова будет вызываться точно так же.

Заключение

Хотя концепция $ .Deferred проста, может потребоваться время, чтобы разобраться с ней. Однако, учитывая природу среды браузера, освоение асинхронного программирования на JavaScript является обязательным требованием для любого серьезного разработчика приложений HTML5, и шаблон Promise (и реализация jQuery) являются огромными инструментами, позволяющими сделать асинхронное программирование надежным и мощным.

Похожие

Как установить приложения с Android на BlackBerry 10?
Возможность играть в приложения для Android на BlackBerry 10 вызывает не только много споров, но и вопросы об этом решении. Как установить, где взять приложения, как загрузить Android Player - это лишь некоторые из вопросов, на которые мы постараемся ответить. Где взять Android-плеер? Вам не нужно загружать или устанавливать программное обеспечение для воспроизведения приложений Android на BlackBerry 10 - это стандартный, базовый и несъемный элемент любого выпуска
Браузер Samsung Internet для Android 4.0 добавляет блокировку контента и многое другое
... сайт может зарабатывать партнерские комиссии по ссылкам на этой странице. Условия эксплуатации , Adblock Plus объявил о своем надстройка фильтра рекламы теперь доступно для некоторых устройств Samsung Galaxy под управлением Android 6.0 Marshmallow. Начиная с марта, он также будет доступен для Samsung Internet для Android 4.0,
Fortnite: Epic Games подает в суд на 14-латку, отвечает его мама / CD-Action
В середине октября мы сообщили, что Создатели Fortnite вступают в борьбу с буквами , Затем Epic Games выпустили прокламацию, которая поощряла игроков сообщать о нарушениях. Как часть страшной студии, она также подала в суд на двух недобросовестных пользователей и потребовала 150 000 от них. компенсация долларов. Причина? Использование прицельных роботов (которые автоматически
Установить браузер Яндекса на Debian, Ubuntu, Fedora, OpenSUSE, Arch
Яндекс браузер хром Интернет-браузер на базе российского поисковика, Яндекс, доступен для Linux, Mac OS X, Windows, Android и iOS. Возможности браузера Яндекса: Синхронизируйте закладки, расширения, данные браузера на ваших устройствах. Современный и чистый пользовательский интерфейс Использует Blink движок для быстрого просмотра
Модульное тестирование и TDD в Node.js - Часть 2
... его зависела CartSummary. В этой статье мы рассмотрим, как писать модульные тесты для того налогового модуля, который отправляет HTTP-запрос. Давайте начнем! Тестирование HTTP-запросов ( Исходный код ) Поэтому вам может быть интересно, как писать модули для функций, которые делают HTTP-запросы. Разве модульные тесты не должны быть изолированными? Да, юнит-тесты
Безопасный браузер для iPad и iPhone
Это правда, что не так много вредоносного ПО существует для MacOS или iOS. Но есть некоторые - и фишинговые сайты, спамеры и кардеры не различают на основе операционной системы. Чтобы защитить вас от этих угроз, мы создали Kaspersky Safe Browser , Помимо предоставления обычных инструментов навигации, он блокирует вредоносные и фишинговые сайты.
Стилизация в действии: от внешнего CSS до стилизованных компонентов
... смотря на то, что многие аспекты создания приложений с помощью React были в некоторой степени стандартизированы, стилизация - это одна из областей, где все еще существует множество конкурирующих вариантов. У каждого есть свои плюсы и минусы, и лучшего выбора нет. В этой статье я приведу краткий обзор прогресса в стилизации веб-приложений по отношению к компонентам React. Я также дам краткое введение в
Повышение платы за Google Карты с 16 июля 2018 года
Эта новость осталась в значительной степени незамеченной в мире Интернета и электронной коммерции. В то время как все остальные были (все еще) заняты GDPR, Google объявил о значительном изменении в использовании API Карт Google, одного из наиболее часто используемых API в мире и чрезвычайно популярного среди электронных продавцов. Google Maps взимать плату за доступ Запущенный в 2005 году, Google Maps, онлайн-картографический сервис Google, стал популярным среди
Создание форм сказочных с HTML5
Вступление Заполнение форм в Интернете никогда не было таким увлекательным занятием, и это может быть очень болезненно на мобильном устройстве с его экранной клавиатурой. Но современные браузеры помогают сделать
Chrome против Firefox: окончательный разбор браузеров для Android
... его подходит для просмотра на мобильных устройствах. Мобильный браузер Chrome Я использую мобильный браузер Chrome с тех пор, как использую смартфоны Android. Обычно он предустановлен, достаточно быстрый для всех моих потребностей и полностью интегрирован со всем на устройстве. Общий просмотр За последние годы мобильный браузер Chrome не сильно изменился. Вы, конечно, можете увидеть, насколько он интегрирован со всеми
Chrome High DPI: как включить его в Windows 8, 8.1 (v34 +)
Не новость в том, что поддержка Chrome для высокого разрешения (hiDPI) уже некоторое время находится в процессе разработки, и в течение последнего года или около того, распространение дисплеев с высоким разрешением на ноутбуках сделало потребность в хорошей поддержке высокого разрешения еще больше важный. Раньше я сталкивался с несколькими бета-функциями, и некоторые из них сделали Chrome полностью непригодным для использования. Я в основном мирился с отсутствием высокого DPI на 13,3-дюймовых

Комментарии

На официальном сайте проекта Tor создатели ответили на вопрос «почему браузер Tor не поддерживает JavaScript?
На официальном сайте проекта Tor создатели ответили на вопрос «почему браузер Tor не поддерживает JavaScript?» Официальный ответ разработчиков браузера Tor на вопрос о JavaScript Ответ заключается в том, что мы не должны ожидать, что создатели отключат JavaScript в браузере Tor.
Будут ли все приложения работать хорошо?
Будут ли все приложения работать хорошо? Также нет. Помните, что мы используем абсолютно простой способ конвертации приложений, поэтому не стоит ожидать никаких чудес. Как установить приложения с Android на BlackBerry 10? Если у нас уже есть правильно конвертированный файл .bar, мы должны быть вооружены: Прежде чем начать всю процедуру, мы должны правильно подготовить наш смартфон: На главном экране проведите
Мы покрыли потрясающие приложения до 10 МБ Недостаточно памяти?
Можно ли устанавливать приложения прямо с телефона? Нет. Как удалить приложения, установленные таким образом? Чтобы удалить приложения, установленные DDPB, просто удерживайте их значок и выберите маленький крестик в правом верхнем углу. Этот метод такой же, как для приложений, загруженных из BlackBerry World, и имеет точно такой же эффект («мусора» не будет).
Что такое Swift и зачем его использовать?
Что такое Swift и зачем его использовать? Swift - это скомпилированный язык программирования для приложений iOS, macOS, watchOS, tvOS и Linux. Вот что вам нужно знать о Swift. Созданный Apple в 2014 году. Поддержанный одной из самых влиятельных технологических компаний в мире, Swift станет доминирующим языком для разработки под iOS и за ее пределами. Открытый исходный код. Создатели Swift признали тот факт, что для создания определяющего
Возможно ли, что вы получите лучший опыт работы с мобильным интернетом, если вместо этого начнете использовать мобильный браузер Firefox?
Возможно ли, что вы получите лучший опыт работы с мобильным интернетом, если вместо этого начнете использовать мобильный браузер Firefox? В этой статье мы рассмотрим все аспекты обоих браузеров, включая все: от обработки вкладок, конфиденциальности, производительности и многого другого. К концу этой статьи вы сможете принять взвешенное решение о том, какой браузер лучше всего подходит для просмотра на мобильных устройствах. Мобильный браузер Chrome Я использую
Это браузер или операционная система?
Это браузер или операционная система? Ответ немного обоих. Это один из самых расширяемых браузеров, которые вы можете использовать. Вы можете получить все, от парольных сейфов до полных текстовых редакторов, которые все живут прямо в вашем браузере. Несмотря на все дополнения, Chrome является сильным конкурентом для самого быстрого браузера. Эта сила
Можно спросить, поскольку JSX переместил разметку в код JavaScript, почему стили должны быть разделены?
Можно спросить, поскольку JSX переместил разметку в код JavaScript, почему стили должны быть разделены? В отличие от разделения стилей и логики, для объединения их в линию могут использоваться разные подходы. Пример этого можно увидеть ниже: <button style = "background: red; border-radius: 8px; color: white;"> Click Me </ button> Встроенные стили перемещают определения CSS из файла CSS. Таким образом, это устраняет необходимость импортировать файл и
Какие решения являются наиболее полезными для его использования?
Какие решения являются наиболее полезными для его использования? Во-первых, подключение к платежной системе (хотя мы в основном используем PayPala), генерирующее электронные письма о статусе заказа. KBK: Интернет-магазин - это одно из ваших занятий, верно? Что еще делает Tattoofest? Как я уже упоминал, наша компания состоит из 4 видов деятельности: студия татуировок «Kult Tattoo Fest», журнал «TattooFest», крупнейший в своем роде конгресс
Вы продаете свой старый компьютер или выбрасываете его в мусорное ведро?
Вы продаете свой старый компьютер или выбрасываете его в мусорное ведро? Простого переформатирования диска недостаточно. Эффективное удаление данных не является решением, используемым только в крупных компаниях. Также типичный Ковальский все больше и больше интересуется судьбой своих файлов при продаже компьютера или самого привода или при вводе оборудования в эксплуатацию. Необратимое стирание содержимого диска является одним из основных способов защиты от попадания конфиденциальной
Могу ли я использовать его на моем телефоне?
Могу ли я использовать его на моем телефоне? Если у вас есть телефон Android, да. Никакой офлайн любви к iPhone, хотя. Могут ли другие телефоны сделать это? Windows Phone может с приложением Nokia Drive. IPhone не может, хотя это может измениться, если Apple действительно представит свою собственную карту. Что если карта неправильная? Google расширяет свой сервис исправлений Map Maker на Южную Африку и Египет, и в ближайшие недели получат выгоду
Теперь, когда вы знаете о USB View, вы можете его скачать и использовать?
Теперь, когда вы знаете о USB View, вы можете его скачать и использовать? Как всегда, если у вас есть комментарии или информация, чтобы поделиться по этой теме, пожалуйста, найдите время, чтобы перейти к TechRepublic Форумы сообщества и позвольте нам услышать от вас. Также прочитайте:

Где взять Android-плеер?
Причина?
Разве модульные тесты не должны быть изолированными?
На официальном сайте проекта Tor создатели ответили на вопрос «почему браузер Tor не поддерживает JavaScript?
Будут ли все приложения работать хорошо?
Будут ли все приложения работать хорошо?
Как установить приложения с Android на BlackBerry 10?
Можно ли устанавливать приложения прямо с телефона?
Как удалить приложения, установленные таким образом?
Что такое Swift и зачем его использовать?

Новости

Карта