Last active
July 2, 2019 11:56
-
-
Save marlo22/78d24f11a423842e95d5f388a28d926e to your computer and use it in GitHub Desktop.
Promise
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
}); | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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