Введение

Мы, люди, даем или получаем обещание выполнить какое-либо действие в определенный момент времени. Если мы сдержим обещание, мы сделаем других счастливыми, но если мы не сдержим обещание, это может привести к недовольству. Обещание в JavaScript имеет что-то общее с приведенными выше примерами.

Обещание — это способ обработки асинхронных операций в JavaScript. Это позволяет обработчикам с возможным значением успеха или причиной отказа асинхронного действия. Это позволяет асинхронным методам возвращать значения, подобные синхронным методам: вместо немедленного возврата конечного значения асинхронный метод возвращает обещание предоставить значение в какой-то момент в будущем.

Обещание находится в одном из следующих состояний:

  • pending: исходное состояние, ни выполнено, ни отклонено.
  • выполнено: это означает, что операция завершена успешно.
  • отклонено: это означает, что операция не удалась.

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

Поскольку методы Promise.prototype.then() и Promise.prototype.catch() возвращают промисы, их можно объединить в цепочку.

Обратные вызовы

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

  • обратный вызов Давайте рассмотрим функцию обратного вызова, которая может принимать два параметра. Первый параметр — это ошибка, а второй — результат. Если параметр err имеет значение false, ошибки не будет, иначе будет возвращена ошибка.

В этом случае ошибка имеет значение, и она вернет ошибочный блок.

//Callback
const doSomething = callback => {
  setTimeout(() => {
    const skills = ['HTML', 'CSS', 'JS']
    callback('It did not go well', skills)
  }, 2000)
}

const callback = (err, result) => {
  if (err) {
    return console.log(err)
  }
  return console.log(result)
}

doSomething(callback)
// after 2 seconds it will print
It did not go well

В этом случае ошибка ложна, и он вернет блок else, который является результатом.

const doSomething = callback => {
  setTimeout(() => {
    const skills = ['HTML', 'CSS', 'JS']
    callback(false, skills)
  }, 2000)
}

doSomething((err, result) => {
  if (err) {
    return console.log(err)
  }
  return console.log(result)
})
// after 2 seconds it will print the skills
["HTML", "CSS", "JS"]

Конструктор обещаний

Мы можем создать обещание, используя конструктор Promise. Мы можем создать новое обещание, используя ключевое слово new, за которым следует слово Promise и скобки. В скобках он принимает функцию callback. Функция обратного вызова обещания имеет два параметра: функции resolve и reject.

// syntax
const promise = new Promise((resolve, reject) => {
  resolve('success')
  reject('failure')
})
// Promise
const doPromise = new Promise((resolve, reject) => {
  setTimeout(() => {
    const skills = ['HTML', 'CSS', 'JS']
    if (skills.length > 0) {
      resolve(skills)
    } else {
      reject('Something wrong has happened')
    }
  }, 2000)
})

doPromise
  .then(result => {
    console.log(result)
  })
  .catch(error => console.log(error))
["HTML", "CSS", "JS"]

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

// Promise
const doPromise = new Promise((resolve, reject) => {
  setTimeout(() => {
    const skills = ['HTML', 'CSS', 'JS']
    if (skills.includes('Node')) {
      resolve('fullstack developer')
    } else {
      reject('Something wrong has happened')
    }
  }, 2000)
})

doPromise
  .then(result => {
    console.log(result)
  })
  .catch(error => console.error(error))
Something wrong has happened

Получить API

Fetch API предоставляет интерфейс для получения ресурсов (в том числе по сети). Он покажется знакомым любому, кто использовал XMLHttpRequest, но новый API предоставляет более мощный и гибкий набор функций. В этом задании мы будем использовать fetch для запроса URL и APIS. В дополнение к этому давайте продемонстрируем пример использования промисов при доступе к сетевым ресурсам с использованием API выборки.

const url = 'https://restcountries.com/v2/all' // countries api
fetch(url)
  .then(response => response.json()) // accessing the API data as JSON
  .then(data => {
    // getting the data
    console.log(data)
  })
  .catch(error => console.error(error)) // handling error if something wrong happens

Асинхронно и ждать

Async и await — это элегантный способ обработки промисов. Это легко понять, и это чисто, чтобы написать.

const square = async function (n) {
  return n * n
}

square(2)
Promise {<resolved>: 4}

Слово async перед функцией означает, что функция вернет обещание. Приведенная выше квадратная функция вместо значения возвращает обещание.

Как мы можем получить доступ к значению из обещания? Чтобы получить доступ к значению обещания, мы будем использовать ключевое слово await.

const square = async function (n) {
  return n * n
}
const value = await square(2)
console.log(value)
4

Теперь, как вы можете видеть из приведенного выше примера, запись async перед функцией создает обещание и для получения значения из обещания мы используем await. Async и await идут рука об руку, одно без другого существовать не может.

Давайте получим данные API, используя как метод promise, так и метод async и await.

  • обещать
const url = 'https://restcountries.com/v2/all'
fetch(url)
  .then(response => response.json())
  .then(data => {
    console.log(data)
  })
  .catch(error => console.error(error))
  • асинхронно и жду
const fetchData = async () => {
  try {
    const response = await fetch(url)
    const countries = await response.json()
    console.log(countries)
  } catch (err) {
    console.error(err)
  }
}
console.log('===== async and await')
fetchData()