Изучение асинхронных методов и получение данных

Асинхронные функции в JavaScript определяются async синтаксисом и возвращают promise. Эти функции работают асинхронно через event loop, использующий неявный promise, который является объектом, который может возвращать результат в будущем.

В рамках языка JavaScript вы можете объявлять асинхронные блоки кода, внутри методов компонента Vue, включив ключевое слово async перед названием метода.

Вы можете использовать методы цепочки промисов, такие как then() и catch(), или попробуйте синтаксис ES6 - await внутри методов Vue.

Вот пример использования встроенного API fetch для получения данных внутри метода компонента с помощью асинхронной функции , используя async/await:

export default {
  methods: {
    async getAdvice() {
      const response = await fetch('https://api.adviceslip.com/advice')
      return response;
    },
  },
}

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

 

Упражнение

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

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

npm install axios

После этого мы можем его импортировать внутри компонента и использовать.

Создадим пустой компонент.

<template>
  <div class="container">
    <h1>Async fetch</h1>
    <button @click="fetchAdvice()">Learn something profound</button>
  </div>
</template>
<script>
  import axios from 'axios'
  export default {
    methods: {
      async fetchAdvice() {
        return axios.get('https://api.adviceslip.com/advice').
        then((response) => {
          console.log(response)
        })
     },
  },
}
</script>

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

Другой пример:

<template>
  <div class="container">
    <h1>Async fetch</h1>
    <button @click="fetchAdvice()">Learn something profound</button>
    <blockquote v-if="quote">{{ quote }}</blockquote>
  </div>
</template>
<script>
import axios from 'axios'
export default {
  data() {
    return {
      axiosResponse: {},
    }
},
computed: {
  quote() {
    return this.axiosResponse && this.axiosResponse.slip ? this.axiosResponse.slip.advice : null
  },
},
methods: {
  async fetchAdvice() {
    return axios.get('https://api.adviceslip.com/advice').
    then(response => {
      this.axiosResponse = response.data
    })
  },
 },
}
</script>

Что здесь происходит:

Мы импортировали axios.

Добавили в data - переменную объект -axiosResponse.

В computed свойстве, мы в свойство quote возвращаем данные, вернее мы смотрим существует ли this.axiosResponse и есть ли this.axiosResponse.slip, если есть то возвращаем -

this.axiosResponse.slip.advice, в противном случае - null.

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

Установите loading в false. Внутри метода fetchAdvice установите loading - true.
Когда запрос GET завершится (resolve/reject), в цепочке finally() верните loading  в false через 4 секунды с использованием функции setTimeout. Вы можете использовать тернарный оператор для изменения текста кнопки между состоянием загрузки и состоянием по умолчанию:

<template>
  <div class="container">
    <h1>Async fetch</h1>
    <button @click="fetchAdvice()">{{ loading ?'Loading...' : 'Learn something profound'}}</button>
    <blockquote v-if="quote">{{ quote }}</blockquote>
 </div>
</template>
<script>
import axios from 'axios'
export default {
  data() {
    return {
      loading: false,
      axiosResponse: {},
    }
  },
  computed: {
    quote() {
      return this.axiosResponse && this.axiosResponse.slip ? this.axiosResponse.slip.advice : null },
    },
    methods: {
      async fetchAdvice() {
        this.loading = true
        try {
          const response = await axios.get(`https://api.adviceslip.com/advice`);
          this.axiosResponse = response.data;
        } 
        catch (error) {
          console.log(error);
        } 
        finally {
          setTimeout(() => {
            this.loading = false;
          }, 4000);
        }
     },
  },
}
</script>

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