Урок 21 из 25
В прогрессе

20) JSON, Promise, async и await

JSON (JavaScript Object Notation) – это текстовый формат представления данных в нотации объекта JavaScript. Предназначен JSON, также как и некоторые другие форматы такие как XML и YAML, для обмена данными.

Как выглядит этот процесс? Его можно представить в виде двух шагов. На первом шаге, сервер, по запросу пришедшему ему от клиента, сначала формирует некоторый набор данных в удобном формате, который затем можно было бы очень просто упаковать в строку JSON. Завершается работа на сервере отправкой JSON данных в качестве результата клиенту. На втором шаге, клиент получает в качестве ответа от сервера строку JSON и распаковывает её, т.е. переводит в JavaScript объект. После этого на клиенте выполняются дальнейшие с ними действия, например, выводятся на страницу.

Структура формата JSON

Структура строки JSON практически ничем не отличается от записи JavaScript объекта.

Она состоит из набора пар ключ-значения. В этой паре ключ отделяется от значения с помощью знака двоеточия (:), а одна пара от другой — с помощью запятой (,). При этом ключ в JSON, в отличие от объекта обязательно должен быть заключен в двойные кавычки. Это первое отличие JSON от JavaScript объекта. В объекте ключ (имя свойства) не обязательно следует заключать в двойные кавычки.

Например:

				
					// строка JSON
var jsonPerson = '{"name":"Иван","age":25}';

// объект JavaScript
var person = {
  name: "Иван",
  age: 25
};
				
			

Второе отличие заключается в том, что значение ключа в JSON можно задать только в одном из следующих форматов: string (строкой), number (числом), object (объектом), array (массивом), boolean (логическим значением true или false) или null (специальным значением JavaScript). Например, значение ключа в JSON не может быть функцией или датой (объектом типа Date).

Работа с JSON в JavaScript

				
					console.log( 'Code is Poetry' );
				
			

Работа с JSON в JavaScript обычно осуществляется в двух направлениях:

  • перевод строки JSON в объект (данный процесс ещё называют парсингом);
  • конвертирование объекта в строку JSON (другими словами действие обратное парсингу).

Парсинг JSON

Парсинг JSON (перевод строки JSON в объект JavaScript) осуществляется с помощью метода eval или parse.

Пример использования eval для парсинга JSON:

				
					var person = eval('('+personData+')');
				
			

Метод eval не рекомендуется использовать так как он не безопасен. Так если кто-то сможет добавить скрипт в строку JSON, то он выполнится.

В JavaScript для парсинга строки в JSON рекомендуется использовать метод JSON.parse. Он такой уязвимости не имеет.

Использование метода JSON.parse:

				
					// переменная person - это объект JavaScript, который получен путём парсинга строки JSON
var person = JSON.parse(personData);
				
			

Конвертирование объекта JavaScript в строку JSON

Перевод объекта JavaScript в строку JSON осуществляется с помощью метода JSON.stringify. Данный метод осуществляет действие обратное методу JSON.parse.

				
					var personString = JSON.strigify(person);
				
			

Promise

Промис (Promise) — специальный объект JavaScript, который используется для написания и обработки асинхронного кода.

Асинхронные функции возвращают объект Promise в качестве значения. Внутри промиса хранится результат вычисления, которое может быть уже выполнено или выполнится в будущем.

Промис может находиться в одном из трёх состояний:

  • pending — стартовое состояние, операция стартовала;
  • fulfilled — получен результат;
  • rejected — ошибка.

Поменять состояние можно только один раз: перейти из pending либо в fulfilled, либо в rejected

Промис создаётся с помощью конструктора.

В конструктор передаётся функция-исполнитель асинхронной операции (англ. executor). Она вызывается сразу после создания промиса. Задача этой функции — выполнить асинхронную операцию и перевести состояние промиса в fulfilled (успех) или rejected (ошибка).

Изменить состояние промиса можно, вызвав колбэки, переданные аргументами в функцию

				
					const promise = new Promise(function (resolve, reject) {
  // Делаем асинхронную операцию: запрос в БД, API, etc.
  const data = getData()
  // Переводим промис в состояние fulfilled.
  // Результат выполнения — объект data
  resolve(data)
})

const errorPromise = new Promise(function (resolve, reject) {
  // Переводим промис в состояние rejected.
  // Результат выполнения — объект Error
  reject(new Error('ошибка'))
})

				
			

Первый параметр (в примере кода назван resolve) — колбэк для перевода промиса в состояние fulfilled, при его вызове аргументом передаётся результат операции.

Второй параметр (в примере кода назван reject) — колбэк для перевода промиса в состояние rejected, при его вызове аргументом передаётся информация об ошибке.