Skip to content

Instantly share code, notes, and snippets.

@marlo22
Last active July 2, 2019 11:56
Show Gist options
  • Save marlo22/78d24f11a423842e95d5f388a28d926e to your computer and use it in GitHub Desktop.
Save marlo22/78d24f11a423842e95d5f388a28d926e to your computer and use it in GitHub Desktop.
Promise
export default getWeather = city => new Promise((resolve, reject) => {
// Wysyłamy zapytanie do jakiegoś API o pogodę na dzisiaj
axios.get(`http://weather.api.com/today/${city}`)
.then(response => {
// ...czekamy aż serwer odeśle odpowiedź
// ...jeszcze chwilka i...
// JEST!
console.log(response) // { temp: 26, weather: 'sunny' }
// Skoro mamy już odpowiedź to możemy oznajmić wszystkim zainteresowanym, że nasz Promise jest resolved.
// Aby to zrobić wystarczy wywołać funkcję, która jest przekazywana jako pierwszy parametr przy wywołaniu new Promise (w naszym przypadku jest to funkcja o nazwie resolve).
// Jako parametr resolve przekazujemy nasz response (chcemy móc później się do niego odwołać w innych miejscach kodu).
resolve(response)
})
.catch(err => {
// Ale przecież backend mógł odmówić posłuszeństwa i co wtedy? Musimy jakoś rozwiązać nasz Promise.
// Aby poinformować wszystkich zainteresowanych, że wystąpił błąd wystarczy po prostu wywołać drugą funkcję przekazaną w konstruktorze Promise, czyli w naszym przypadku reject.
// Możemy także przekazać obiekt błędu, który zwrócił serwer.
reject(err);
});
});
import getWeather from './action.js';
// Spróbujmy wywołać naszą funkcję...
console.log(getWeather()) // coś nie tak... konsola wyświetliła: Promise {<pending>}. Oznacza to, że funkcja zwraca Promise, ale nie została jeszcze rozwiązana.
// Aby zaczekać na to aż Promise zostanie rozwiązany możemy użyć klasycznego .then, czyli:
getWeather()
.then(response => {
// Jeśli w Promise funkcji getWeather() zostanie wywołana funkcja resolve() to wykona się ten blok .then.
// Co więcej - to co przekazaliśmy jako parametr do resolve() zostanie wrzucone tutaj jako parametr response czyli:
console.log(response) // ten log wyświetli nic innego jak dobrze znany nam obiekt { temp: 26, weather: 'sunny' }
})
.catch(err => {
// Oczywiście może również wystąpić błąd. Aby odpalił się ten blok .catch nasza Promise w funkcji getWeather() musi wykonać funkcję reject. Jako parametr err zostanie przekazany obiekt, który przekezaliśmy jako parametr funkcji reject().
console.error('Wystąpił błąd podczas pobierania informacji pogodowych!', err);
});
// Jest jeszcze jeden sposób na obsługę Promise, a mianowicie async/await.
import getWeather from './action.js';
// Ale aby móc skorzystać z await musimy najpierw owinąć cały kod w funkcję asynchroniczną - poza nią nie ma możliwości skorzystania z await. A więc:
async function callGetWeather() {
// Odpalaną funkcję owijamy również w blok try-catch, bo w przeciwnym wypadku, gdy w Promise wystąpi błąd kod nie wykona się dalej!
try {
const ciekaweCoTuJest = await getWeather();
// Poniższa linijka nie wykona się dopóki getWeather w Promise nie wywoła funkcji resolve.
console.log(ciekaweCoTuJest); // Jak myślisz, co kryje się pod tą zmienną? Właśnie tak! :D Obiekt { temp: 26, weather: 'sunny' }
// Kolejną super zaletą async/await jest to, że nie musimy np. w Reduxowych akcjach przekazywać żadnych callbacków do wywołania zamknięcia modala, wyświetlania informacji o (nie)powodzeniu operacji, albo wyłączenia loadera.
// Jeśli chcielibyśmy np. zamknąć modal i wyświetlić informacje o sukcesie wystarczy poniżej await wywołać odpowiednie funkcje, np.:
showSuccess('Informacje pobrane');
closeModal();
// i... tyle! Nic więcej nie potrzeba.
// Funkcje showSuccess i closeModal zostaną wykonane dopiero po tym jak funkcja await getWeather() wykona się.
} catch (err) {
// To samo co w poprzednim przykładzie - Promise funkcji getWeather wywołuje reject? Trafia to do tego bloku.
console.error('Wystąpił błąd podczas pobierania informacji pogodowych!', err);
// Możemy oczywiście wyświetlić alert o błędzie.
showError('Chyba idzie burza...');
} finally {
// Jakby tego było mało mamy jeszcze do dyspozycji blok finally, w który możemy np. wyłączyć spinner, który pojawia się przy fetchowaniu danych. Ten kod wykona się niezależnie od tego czy funkcja getWeather powiodła się czy nie.
hideSpinner();
}
}
// I na koniec wywołujemy nasz asynchroniczny wrapper.
callGetWeather();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment