Концепции промисов трудно полностью понять, это было для меня и остается в некоторых сценариях, но обладание этими знаниями выделит вас.

Что такое обещание?

Это объект, представляющий результат асинхронного вычисления. Результат может быть еще не готов, а Promise API намеренно не раскрывает этого: нет способа синхронно получить значение промиса; вы можете только попросить Promise вызвать функцию обратного вызова, когда значение будет готово.

getJson(url).then(jsonData) => {
//this is a callback function that will be asynchronosly 
//invoked with the parsed JSON value when it becomes avalable
});

//Supose you have a function that display a user profile
function displayUserProfile(profile) {
/* your code */
}

//here is how you may use that function with a promise
getJson("api/user/profile").then(displaUserProfile);

Вы можете думать о методе регистрации обратного вызова метода then() как о методе addEventListnener(), используемом для регистрации обработчиков событий в JS на стороне клиента. Однако обещание представляет собой одно вычисление, и каждая функция, зарегистрированная с помощью then(), будет вызываться только один раз.

import { useState, useEffect } from 'react';

//Child component
function SearchResults({ results }) {
  if (!results) {
    return null;
  }

  return (
    <ul>
      {results.map(result => (
        <li key={result.id}>
          <h2>{result.title}</h2>
          <p>{result.overview}</p>
        </li>
      ))}
    </ul>
  );
}

//Parent component
function SearchMovies() {
  const [query, setQuery] = useState('Star Wars');
  const [results, setResults] = useState(null);

  useEffect(() => {
    const apiKey = 'your-api-key-here';
    const url = `https://api.themoviedb.org/3/search/movie?api_key=${apiKey}&query=${query}`;

    fetch(url)
      .then(response => response.json())
      .then(data => setResults(data.results))
      .catch(error => console.error(error));
  }, [query]);

  return (
    <div>
      <input type="text" value={query} onChange={event => setQuery(event.target.value)} />
      <SearchResults results={results} />
    </div>
  );
}

В приведенном выше примере React есть компонент SearchResult, который отображает результат фильмов, который использует useState для отслеживания поискового запроса и повторно извлекает результаты из fetch API при изменении состояния.

Цепочка обещаний

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

fetch(documentURL)                      //Make a HTTP request
  .then(response => response.json())    //Ask for the JSON body for the request
  .then(document => {                   //When we get the parsed JSON
   return render(document);            //display the documet to the user
})
  .then(rendered => {                  //When we get the rendered document
      cacheInDatabase(rendered);       //chache it in the local database.
    })
.cache(error => handle(error));        //Handle any errors that occur

Код показывает, как цепочка промисов может упростить выражение последовательности асинхронных операций. Когда Promise, возвращаемый функцией fetch(), выполняется, он передает объект Response функции, которую вы передали ее методу then.

Давайте посмотрим на другой пример с React и аксиомами?

import React, { useState, useEffect } from 'react';
import axios from 'axios';

function UserProfile() {
  const [profile, setProfile] = useState(null);
  const [profileGroups, setProfileGroups] = useState(null);
  const [error, setError] = useState(null);

  useEffect(() => {
    axios.get('api/user/profile')
      .then(response => {
        setProfile(response.data);
        return axios.get(`api/user/profile/groups/${response.data.id}`);
      })
      .then(response => {
        setProfileGroups(response.data);
      })
      .catch(error => {
        setError(error);
      });
  }, []);

  if (error) {
    return <div>{error.message}</div>;
  }

  if (!profile) {
    return <div>Loading...</div>;
  }

  return (
    <div>
      <h2>{profile.name}</h2>
      <p>{profile.bio}</p>
      <p>{profile.email}</p>
      {profileGroups && (
        <ul>
          {profileGroups.map(group => (
            <li key={group.id}>{group.name}</li>
          ))}
        </ul>
      )}
    </div>
  );
}

export default UserProfile;

Цепочка промисов может показаться немного более сложной, но в этом примере сначала мы отправляем запрос на получение информации о профиле пользователя. Когда он будет получен, мы используем идентификатор из этого ответа, чтобы сделать еще один запрос на получение групп пользователей. и установите состояние profileGroups на основе ответа так же, как setProfile.

Чем больше я работал с API, тем более глубокое понимание мне приходилось приобретать как во фронтенде, так и в бэкенде. Есть и другие концепции, которые нужно охватить, такие как разрешение обещаний, методов catch и finally, обещание параллельно, но с теми, которые я рассмотрел, я лично столкнулся чаще всего.

Похожие истории







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

Подпишитесь на нашу бесплатную еженедельную рассылку новостей. Подпишитесь на нас в Twitter, LinkedIn, YouTube и Discord .

Заинтересованы в масштабировании запуска вашего программного обеспечения? Ознакомьтесь с разделом Схема.