Получение данных от сервера в jQuery
В этом видео мы с вами разберем, как писать запросы к серверу в javascript используя jQuery.
Напоминаю, что идея состоит в том, чтобы получить данные от сервера асинхронно с помощью HTTP-запроса и изменить страницу у пользователя без перезагрузки.
Для того, чтобы обращатся на сервер за данными, давайте создадим API с тестовыми данными с помощью сервиса mocky.io.
Вот у меня есть JSON данных
[ { "userId": 1, "id": 1, "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit", "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto" }, { "userId": 1, "id": 2, "title": "qui est esse", "body": "est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui aperiam non debitis possimus qui neque nisi nulla" }, { "userId": 1, "id": 3, "title": "ea molestias quasi exercitationem repellat qui ipsa sit aut", "body": "et iusto sed quo iure\nvoluptatem occaecati omnis eligendi aut ad\nvoluptatem doloribus vel accusantium quis pariatur\nmolestiae porro eius odio et labore et velit aut" } ]
Вставляем его в body запроса и в advance mode выбираем
Access-Control-Allow-Origin:*
Для того, чтобы любой домен мог обращатся к этому API.
Нажимаем Generate response и получаем ссылку на наш API.
Теперь давайте посмотрим на мою заготовку для урока. Это просто базовый html файл, в который подключено два скрипта jquery и code.js в котором мы будем писать код.
Давайте напишем код, который получит данные от сервера.
var promise = $.ajax({ url: 'http://www.mocky.io/v2/5944e07213000038025b6f30' })
Очень важно помнить, что в результате выполнения мы получаем не данные, а промис. Это значит, что мы можем подписаться на получение данных из промиса с помощью .then, передав туда callback. Тогда первым аргументом, мы получим наши данные.
$.ajax({ url: 'http://www.mocky.io/v2/5944e07213000038025b6f30' }).then(function (result) { console.log('result', result) })
Если мы посмотрим в браузер, то у нас вывелся в консоль наш массив обьектов.
Что делать если мы хотим обработать ошибку? Нам нужно подписаться с помощью .catch на error.
$.ajax({ url: 'http://www.mocky.io/v2/5944e07213000038025b6f30' }). then(function (result) { console.log('result', result) }).catch(function (err) { console.log('err', err) })
Если мы изменим ссылку на неправильную то попадем в error.
В $.ajax можно также использовать методы done и fail, которые являются аналогами then и catch, но я советую придерживаться в работе с любыми промисами использования then и catch, так как это ближе к стандарту. Например в es6 промисах у вас тоже будут the и catch, а это значит, что код будет выглядит одинаково.
В $.ajax можно задавать множество разнообразных опций, но я перечислю только самые используемые из них.
Первое это конечно method. По умолчанию он get и мы можем менять его например на post, чтобы отправить post запрос.
$.ajax({ method: 'POST', url: 'http://www.mocky.io/v2/5944e07213000038025b6f30' }).then(function (result) { console.log('result', result) }).catch(function (err) { console.log('err') })
Конечно чаще всего в POST запрос мы хотим передать какие-то данные. В этом нам поможет поле data
$.ajax({ url: 'http://www.mocky.io/v2/5944e07213000038025b6f30', method: 'POST', data: { test: 1 } }).then(function (result) { console.log('result', result) }).catch(function (err) { console.log('err') })
Если мы посмотрим в network, то увидим, что данные у нас передаются.
Также в jQuery есть алиасы метода $.ajax. Это $.get, $.post, $.getJSON, которые хоть и более короткие, но на мой взгляд менее читабельные и лучше придерживаться полной записи.
Напоминаю, что $.ajax, это всего лишь обертка нам стандартным для javascript XMLHttpRequest.
Какие же основные преимущества она нам дает?
- Как результат выполнения мы получаем промис, а это значит с ним очень удобно работать с помощью .then и .catch
- Очень простое API. Мы просто указываем обьектом опции и все работает.
Если у вас что-то не получается, либо возникли вопросы и комментарии, пишите их прямо под этим видео и я обязательно на них отвечу.
… и я по-прежнему считаю, что Mootools лучше, чем jQuery
Когда я впервые начал заниматься веб-разработкой, я начал использовать прототип.js и его библиотеку анимаций scriptaculous (удивительно, но эти сайты все еще работают в 2020 году). Работа с несоответствиями веб-браузера была ужасной, но Prototype скрыл все это и сделал работу в Интернете намного приятнее. Анимации, которые можно было сделать с помощью scriptaculous, поразили меня в то время. Было так легко заставить вещи появляться или исчезать, исчезать. Все мои друзья были впечатлены.
Затем начались войны фреймворков JS. Были YUI, Dojo, Mootools, jQuery и, конечно же, Prototype. Сначала я все еще придерживался Prototype, но начал экспериментировать с YUI для их виджетов. YUI уже мертв, но черт возьми, их виджеты были великолепны. У них определенно были лучшие виджеты 2009 года, ИМХО, но я отвлекся…
Mootools
В конце концов я попробовал Mootools и влюбился в него. Это было похоже на Prototype, только более модульное, более стандартизированное, просто лучше во всех отношениях. Это было одновременно просто в использовании, но мощно. Это не только упростило взаимодействие с DOM; как и Prototype, он также упростил работу со строками, добавил множество методов массива/коллекции, имел несколько хороших методов класса и, конечно же, анимацию. Это был сон. Это сделало работу в Javascript намного лучше во всех отношениях.
Затем jQuery начал выигрывать. Внезапно все начали использовать jQuery, а все остальные фреймворки были заброшены. Я пробовал jQuery, но ненавидел его. Конечно, работать с DOM стало приятнее, но с остальной частью JS ничего не изменилось. Плюс ко всему был метод на этом единственном объекте $
, который меня почему-то сильно напрягал. Конечно, он не затрагивал никаких встроенных объектов, таких как массивы или строки, но в результате работать с ним было намного раздражительнее. Каждая строка JS начинается с $(...)
или $.something
, и мне пришлось вернуться к использованию старого дрянного сырого JS без каких-либо языковых помощников, предоставляемых Mootools.
Почему это произошло? Внезапно все библиотеки Mootools, на которые я полагался, перестали получать обновления, и никто больше не делал ничего интересного для Mootools. Ясно, что jQuery победил, и поэтому я угрюмо переписал свои проекты на jQuery, где только мог, а оставшиеся части Mootools превратились в музей, заполненный паутиной. Я все еще чувствовал, что Интернет сделал неправильный выбор, что Mootools определенно лучше, чем jQuery, но я понял, что когда все веб-сообщество движется к консенсусу, вам тоже нужно двигаться. Оказывается, выбор Mootools вместо jQuery изначально был лишь первым в длинной череде моих неудачных технических решений.
Coffeescript
Примерно в то же время Coffeescript стал очень популярным. Rails начал активно продвигать Coffeescript в Rails 3 примерно в то же время, когда они официально перешли с Prototype.js на jQuery. Я попробовал Coffeescript и влюбился. Coffeescript помог заполнить некоторые дыры в основном языке JS, оставшиеся после переключения Mootools на jQuery. Неожиданно появились настоящие классы, стрелочные функции (больше никаких привязок к этому
везде!), шаблонные строки, ==
, которые работали правильно, и многое другое. Я начал использовать Coffeescript для всего, и мне это понравилось. Это не могло пойти не так…
Backbone
Затем, примерно в 2012 году, произошел еще один взрыв фреймворков JS, от Batman.js до Knockout, Backbone, Angular и многих других. На этот раз я ловко дождался, пока в сообществе не будет явного победителя, прежде чем переходить на фреймворк, так как понял, что неправильный выбор означает и разочарование, и огромное количество потраченного времени на разучивание и переписывание всего написанного на что-то новое.
И на этот раз явным победителем стал Backbone JS. Итак, я начал узнавать об этом и писать проекты в нем. Hacker News согласились с этим, Backbone был там, где он был, и если вы не использовали Backbone, вы определенно потерпели неудачу. Все об этом писали, крупные компании выпускали проекты и плагины для него. Не может быть, чтобы это было неправильно!
…А потом через год все решили, что Backbone хромает, и все сообщество снова потеряло к нему интерес. Я действительно думал, что на этот раз был на правильной стороне истории, но явно не так. Теперь речь шла об Angular, Ember и React. Я снова высидел, устав от того, что снова и снова обжигаюсь, выбирая неправильный фреймворк, затем зализывая свои раны и переписывая все, что я сделал.
Более того, примерно в это же время язык Javascript начал получать множество улучшений, и все начали использовать Browserify для переноса нового Javascript в старый Javascript, поддерживаемый в настоящее время браузерами. Этот новый Javascript включает в себя множество замечательных языковых функций, которые были в Coffeescript. В результате Coffeescript начал умирать. Теперь у меня осталось множество бесполезного кода Coffeescript, который мне нужно было переписать обратно в простой Javascript. Вздох…
🎉 Реагировать
Наконец, примерно в 2015 году я начал изучать React. Оглядываясь назад, я думаю, что это первое правильное техническое решение, которое я принял (по состоянию на 2020 год — кто знает, что произойдет через 6 месяцев). Я не изучал Angular или Ember, и, к счастью, пока это кажется правильным выбором. Тем не менее, у меня было еще много плохих технологий впереди!
Flow
Добавление типов в JS стало очень популярным примерно в 2016 году, когда появились Typescript и Flow. Естественно, я решил, что Flow выглядит великолепно, поскольку это была простая аннотация, которую можно было добавить в файлы JS, поэтому решил использовать ее для всего. Затем Facebook перестал воспринимать Flow всерьез, и проект потерпел неудачу. Отлично, теперь у меня есть куча бесполезного Flow-кода, который нужно переписать на Typescript…
🎉 GraphQL
Я начал использовать GraphQL для своих проектов примерно в 2017 году, и, к счастью, это был правильный выбор. Популярность GraphQL только растет, и все его конкуренты, такие как OData или Falcor, похоже, мертвы. Я определенно могу ошибаться, но мне кажется, что GraphQL никуда не денется!
Relay
Facebook запустил Relay, чтобы упростить работу с GraphQL и React. Потрясающий! Естественно, я решил использовать Relay для всех своих проектов, использующих GraphQL и React. Затем Facebook последовал той же схеме, что и с Flow, и позволил проекту постепенно прийти в упадок. Теперь Apollo определенно выиграл войны GraphQL, поэтому теперь мне нужно попробовать переписать весь мой код Relay с помощью Apollo. Вздох.
Create React App
Я начал использовать Create React App для настройки внешних проектов в React, так как возиться с Webpack и Babel напрямую — это упражнение в чистом мазохизме. Это, опять же, оказалось ошибкой, так как Гэтсби был очевидным способом создания статических веб-сайтов с помощью React. Теперь мне нужно обновить эти проекты, чтобы вместо этого использовать Gatsby…
После того, как я выбрал проигравшую лошадь в столь многих гонках внешнего интерфейса JS, я хотел бы найти способ избежать всего этого. Есть ли какая-то метрика, которую я мог бы отслеживать, чтобы знать, когда пора переходить на новую технологию, и когда она проиграет через 6 месяцев? Может быть, мне следует более внимательно следить за Google Trends и принимать соответствующие решения? Нет ничего более жалкого, чем тратить кучу времени на изучение новой технологии, а затем отменять все, что вы сделали, и заново изучать то, что сейчас популярно. И мой послужной список выбора технологий действительно плохой — я сделал правильный выбор, который не требовал значительных переписываний примерно в 25% случаев. Если есть лучший способ, дайте мне знать!
Обработка последовательных вызовов AJAX с использованием jQuery
ПроблемаНеобходимо выполнять несколько вызовов AJAX параллельно для получения необходимых данных, и каждый последующий вызов зависит от данных, полученных в предыдущем вызове. Поскольку AJAX является асинхронным , невозможно контролировать порядок выполнения вызовов. Из-за такого поведения возникает несоответствие в данных, которые будут привязаны к ИП .
Пример из реальной жизни
Наша команда работала над приложением, которое интегрировало в него все отчеты, созданные с помощью Microsoft Power BI , и конечные пользователи, в зависимости от их уровней доступа, могли просматривать отчеты и другие связанные данные. . У нас также была система управления пользователями , откуда администраторы могли управлять другими пользователями и ограничивать данные, к которым у них есть доступ.
На одном из экранов у нас есть требование отобразить все Доступные отчеты в системе в одном раскрывающемся списке и все Назначенные отчеты пользователю в другом раскрывающемся списке, как показано на рисунке ниже.
Здесь нам нужно было сделать два вызова AJAX, чтобы получить данные для раскрывающихся списков выше. Один вызов будет получать назначенные отчеты, а затем следует вызвать другой, чтобы получить все доступные отчеты, которые будут отфильтрованы на основе данных, которые уже были получены в первом вызове, чтобы получить фактически доступные отчеты.
Назначенные отчеты = Назначенные отчеты
Доступные отчеты = Общее количество доступных отчетов – Назначенные отчеты
Раньше мы просто вызывали эти функции одну за другой.
Из-за асинхронного поведения иногда функция getAvailableReports() использовалась для попадания в первую очередь, что приводило к выборке несогласованных данных в раскрывающиеся списки Доступные отчеты , как показано ниже.
Решения 1. Традиционный подход к решению этой проблемы из getMappedReports() , как показано в приведенном ниже коде
Если необходимо выполнить несколько последовательных вызовов AJAX , как показано на изображении ниже, то приведенный выше подход делает код менее читаемым. Это привело бы к большому количеству вложенных обратных вызовов, которые необходимо синхронизировать, что часто называют «9».0065 ад обратного вызова.
2. Общий и повторно используемый подход
- jQuery.when() предоставляет способ выполнения функций обратного вызова на основе нуля или более объектов Thenable, обычно отложенных объектов, представляющих асинхронные события . jQuery.when() принимает отложенных (отложенных, обещанных или объектов Thenable)
- Начиная с jQuery 1.5, jQuery.Ajax() является объектом Promise-Compatible , что означает, что он вернет разрешенный объект обещания
- deferred.then() — это обработчик, который вызывается, когда отложенный объект разрешается, отклоняется или все еще выполняется
Теперь, объединив вышеуказанные концепции, мы можем сделать два ajax-запроса один за другим, как показано ниже.
Однако есть небольшая проблема. Функция jQuery.when() принимает списки аргументов, поэтому мы должны передавать их следующим образом, если у нас есть несколько последовательных вызовов ajax:
Но что, если у нас есть сотни вызовов ajax? Нам нужен способ преобразовать эти вызовы ajax из jQuery.
Когда мы вызываем функцию jQuery.when() , ключевое слово this внутри функции неявно связывается с объектом jQuery. Но когда мы вызываем jQuery.when.apply() , мы должны явно связать ключевое слово с чем-то. И мы знаем, что привязка должна быть с объектом jQuery, поэтому мы передаем объект jQuery, также известный как $, в качестве первого аргумента.
Поскольку мы знаем, что каждый jQuery.ajax() возвращает отложенный объект , мы можем вернуть список таких отложенных объектов в качестве аргумента функции jQuery.when.apply(), как показано ниже. Теперь решение выглядит более чистым, читабельным, ремонтопригодным и пригодным для повторного использования.
Обещания позволяют избежать неприятных трюков для синхронизации параллельных или последовательных асинхронных функций и необходимости вкладывать обратные вызовы внутри обратных вызовов внутри обратных вызовов.