Skip to content

Latest commit

 

History

History
341 lines (217 loc) · 11.2 KB

File metadata and controls

341 lines (217 loc) · 11.2 KB
title Занятие 4.2
description Базовое использование API и JavaScript. Как работать с сетевыми ресурсами

OTUS

Javascript Basic

Вопросы?

Базовое использование API и JavaScript.

Как работать с сетевыми ресурсами

Асинхронный код - минимум для работы

Подробнее будет в третьем модуле на занятии про асинхронный код

JS - ОДНОПОТОЧНЫЙ ЯЗЫК

  • Отрисовка DOM
  • Обработка пользовательского ввода
  • Выполнение JS кода
  • Среда выполнения содержит очередь событий (список событий, подлежащих обработке)
  • Каждое событие ассоциируется с некоторой функцией.
  • Каждый вызов функции добавляет запись в стек
  • При завершении функции запись изымается из стека
  • Когда стек освобождается, событие извлекается из очереди и обрабатывается (функция вызывается).

На бытовом уровне мы могли бы это объяснить так...

Демонстрация

Поэтому операции, которые занимают длительное (больше 50 ms) операции стараются

  • переложить на внешнего исполнителя
  • отложить исполнение и разбить на части

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

Как работать с таким асинхронным кодом? Как это выглядит?

// работа с callback-функциями
const x = 2;
// результат мы можем обработать в callback-функции
calculateSomethingAsyncWithCallback(x, (result) => {
  console.log(result);
});
// в node.js было принято
calculateSomethingAsyncWithCallback(x, (error, result) => {
  if (error) {
    return console.error(error);
  }
  // ...
});
// работа с callback-функциями
const x = 2;
calculateSomethingAsyncWithCallback(x, (result) => {
  calculateSomethingElseAsyncWithCallback(result, (secondResult) => {
    console.log(result);
  });
});

Вопросы?

Для решения проблемы callback hell ввели интерфейс Promise.

function doSomething() {
  return new Promise((resolve, reject) => {
    console.log("Готово.");
    // Успех в половине случаев.
    if (Math.random() > 0.5) {
      resolve("Успех");
    } else {
      reject("Ошибка");
    }
  });
}

const promise = doSomething();
promise.then(successCallback, failureCallback);
promise.then(successCallback).catch(failureCallback);
calculateSomethingAsyncWithPromise(x)
  .then((result) => calculateSomethingElseAsyncWithPromise(result))
  .then((secondResult) => console.log(secondResult));

Вопросы?

Но в Javascript приходит все больше и больше людей с других языков, и им непривычно читать такой код. Кроме того он имеет некоторые проблемы (например нам нужен одновременный доступ к result и secondResult).

Появились async функции. Которые предоставляют await механизм.

Мы можем пометить функцию ключевым словом async. Это дает следующее:

  1. функция теперь неявно возвращает Promise

  2. внутри функции мы можем использовать ключевое слово await для разворачивания Promise-результатов

(async function () {
  const x = 2;
  const result = await calculateSomethingAsyncWithPromise(x);
  const secondResult = await calculateSomethingElseAsyncWithPromise(result);
  console.log(secondResult);
})();

Top-level await.

const x = 2;
const result = await calculateSomethingAsyncWithPromise(x);
const secondResult = await calculateSomethingElseAsyncWithPromise(result);
console.log(secondResult);

Краткий итог:

  • некоторый функции нужно вызывать с ключевым словом await
  • await работает только внутри функций, которые помечены как async и в top-level

Подробнее мы будем разбирать на занятии про асинхронность

Вопросы?

И еще одно отступление про асинхронность (мы будем об этом говорить подробнее на занятии по дизайну вашего API)

В разработке принято писать на уровне интерфейсов (абстракций), а не реализаций. То есть вы должны знать ЧТО делает функция или модуль, но не КАК.

Когда вы начинаете использовать детали реализации - это называется "протекающая абстракция".

Типичные кандидаты на асинхронные операции:

  • запрос данных от пользователя
  • сохранение и чтение данных
  • обращение к стороннему сервису
  • валидации и сложные вычисления

Но при этом

  • для запроса данных от пользователя есть синхронные alert / prompt
  • для чтения и сохранения данных есть синхронный localStorage

Лучше сразу заложить возможность для расширения, и использовать асинхронные обертки. Тогда в любой момент можно будет поменять реализацию, и вместо localStorage сохранять данные на сервере, например. А вместо alert показывать красивое стилизованное модальное окно (которое не блокирует поток).

async function asyncPrompt(request) {
  return prompt(request);
}
// const x = asyncPrompt(); работать не будет
const x = await asyncPrompt();

Вопросы?

Для работы с HTTP запросами у нас есть два варианта (на самом деле больше, если подключать библиотеки):

fetch - поддерживается современными браузерами, предоставляет Promise-based интерфейс (удобен для async функций) и прост в использовании.

// await-friendly окружение
let response = await fetch(url);

let text = await response.text();

console.log(text);
// await-friendly окружение
let response = await fetch("/article/fetch/post/user", {
  method: "POST",
  headers: {
    "Content-Type": "application/json;charset=utf-8",
  },
  body: JSON.stringify(user),
});

let jsonData = await response.json();
console.log(jsonData);

fetch возвращает вам объект типа Response.

Чаще всего используются

  • поле ok
  • поле status
  • методы text() и json()

Вопросы?

Практика

OpenWeather API

Вопросы?

Дополнительное задание:

при заходе на страницу показать пользователю погоду в его городе. Для получения этой информации можно сделать запрос на https://get.geojs.io/v1/ip/geo.json, который вернет данные в формате JSON.

GeoAPI

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

Сайт с прогонозом погоды

Само домашнее задание у вас будет позже, но уже сейчас вы можете выполнять часть, связанную со страницей.

Вопросы?

Дополнительные материалы

  1. Путеводитель по JavaScript Promise для новичков
  2. Public APIs
  3. JavaScript. Как работать с API Telegram, Youtube и VK
  4. Что на самом деле происходит, когда пользователь вбивает в браузер адрес google.com

Вопросы для самопроверки

  1. Что такое CORS?

  2. Что такое и какие есть коды ответов HTTP?

  3. Что такое jsonp-запрос?

  4. Быть в состоянии рассказать что такое XHR, AJAX, CDN

  5. Чем XMLHTTPRequest отличается от fetch?