manche Aufgaben in JavaScript können gleichzeitig laufen (insbesondere Aufgaben bezüglich Input / Output):
Möglichkeiten, um Netzwerkanfragen zu machen:
Beispiel: Anfragen mit axios (await), axios (then) und jQuery (callback):
const res = await axios(url);
console.log(res.data);
axios(url).then((res) => console.log(res.data));
jquery.getJSON(url, (data) => console.log(data));
Promise: Repräsentation eines zukünftigen Ergebnisses, das nicht unmittelbar verfügbar ist
Beispiel aus der echten Welt:
Wir bestellen bei einem Fast-Food-Restaurant und erhalten folgenden Bon:
Bestellung #42:
- Cheeseburger
- kleine Pommes
Die Bestellung wird - sobald bereit - zu Ihrem Tisch gebracht.
Der Bon ist ein "Promise" - eine Repräsentation eines zukünftigen Ergebnisses
Das warten auf ein Promise ist non-blocking: anderer Code währenddessen ausgeführt werden
warten auf das resolven eines Promises:
.then()
await
// request the home page (/)
fetch('/')
// wait for a response, then request its text content
.then((res) => res.text())
// wait for the text content, then log it
.then((content) => console.log(content));
kann in der Browserkonsole für jede geöffnete Website ausgeführt werden
Das Abfragen einer URL und das Auslesen des Antworttexts können länger dauern.
Mit .then()
warten wir jeweils auf das Resultat.
Die Funktion .then()
bekommt einen Handler (in Form einer anderen Funktion) übergeben.
Das Resultat des ersten Handlers ((res) => res.text()
) ist wiederum ein neues Promise.
Der zweite Handler ((content) => console.log(content)
) loggt das Resultat.
Beispiel: Fetch von JSON-Daten - zwei Funktionen, die Promises zurückgeben
const fetchTodos = () => {
return fetch(
'https://jsonplaceholder.typicode.com/todos'
).then((res) => res.json());
};
const fetchTodos = async () => {
const res = await fetch(
'https://jsonplaceholder.typicode.com/todos'
);
const todos = await res.json();
return todos;
};
Nach dem aktuellen ES Standard muss ein await
-Statement immer in einer async
-Funktion beinhaltet sein
Fortschritt des "top level await" (await außerhalv von of async
-Funktionen):
Vorteile von await
:
Vorteile von .then
:
fetch(url, {
method: 'POST',
cache: 'no-cache',
body: '{"text": "learn fetch"}',
headers: { 'content-type': 'application/json' },
});
Verschiedene Fehler können beim Fetch auftreten:
Abfangen von möglichen Fehlern:
fetch('https://jsonplaceholder.typicode.com/todos')
.then((res) => res.json())
.then((data) => console.log(data))
.catch((err) => console.log(err));
Standardmäßig wird eine Antwort mit einem Fehlercode (z.B. 404 oder 500) auch als Erfolg angesehen.
const fetchTodos = async () => {
const res = await fetch(
'https://jsonplaceholder.typicode.com/todos'
);
if (!res.ok) {
throw new Error(res.statusText);
}
const todos = await res.json();
return todos;
};
Promise, die nach 1 Sekunde entweder mit hello antwortet oder nicht erfolgreich ist
const getReply = new Promise((resolve, reject) => {
setTimeout(() => {
if (Math.random() > 0.5) {
resolve('hello');
} else {
reject('no access');
}
}, 1000);
});
Erstellen eines Promise, das resolved wird, wenn mehere asynchrone Tasks abgeschlossen sind:
const fetchJson = async (url) => {
const res = await fetch(url);
return await res.json();
};
const [users, todos] = await Promise.all([
fetchJson('https://jsonplaceholder.typicode.com/users'),
fetchJson('https://jsonplaceholder.typicode.com/todos'),
]);
Das erste erfolgreiche Promise als Resultat verwenden:
const anyTodo = await Promise.race([
fetchJson('https://jsonplaceholder.typicode.com/todos/1'),
fetchJson('https://jsonplaceholder.typicode.com/todos/2'),
fetchJson('https://jsonplaceholder.typicode.com/todos/3'),
]);
verbreitete Library mit mehr Funktionalität / einfacherem Interface als fetch
JSON Daten laden:
const todos = await axios(
'https://jsonplaceholder.typicode.com/todos'
);
Standardverhalten:
fetch('https://jsonplaceholder.typicode.com/todos')
.then(res => res.json())
.then(data => console.log(data));
import axios from 'axios';
axios('https://jsonplaceholder.typice.com/todos')
.then(res => console.log(res.data));
fetch('https://www.w3.org')
.then(res => res.text())
.then(content => console.log(content));
axios('https://www.w3.org', { responseType: 'text' })
.then(content => console.log(content));
Achtung: Standardmäßig versucht axios zumindest, den Inhalt als JSON zu parsen
fetch('https://jsonplaceholder.typicode.com/todos', {
method: 'post',
body: '{"title": "xyz"}',
headers: { 'Content-Type': 'application/json' },
});
axios.post(
'https://jsonplaceholder.typicode.com/todos',
'{"title": "xyz"}',
{ headers: { 'Content-Type': 'application/json' } }
);
const query = '{pokemon(name: "Pikachu") {number name}}';
const body = JSON.stringify({ query: query });
fetch('https://graphql-pokemon.now.sh', {
method: 'post',
body: body,
headers: { 'Content-Type': 'application/json' },
})
.then(res => res.json())
.then(data => console.log(data.data));
const query = '{pokemon(name: "Pikachu") {number name}}';
const body = JSON.stringify({ query: query });
axios
.post('https://graphql-pokemon.now.sh', body, {
headers: { 'Content-Type': 'application/json' },
})
.then(res => console.log(res.data.data));
Beispiele:
axios.defaults.baseURL = 'https://api.example.com';
axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
axios.defaults.headers.post['Content-Type'] =
'application/x-www-form-urlencoded';
const todosAxios = axios.create({
baseURL: 'https://jsonplaceholder.typicode.com/todos',
timeout: 2000,
});
todosAxios.get('/').then(console.log);
todosAxios.get('/1').then(console.log);
Interceptors sind Middleware, die beim Senden / Empfangen von Daten ausgelöst wird
const requestLogger = requestConfig => {
console.log('sending request', requestConfig);
return requestConfig;
};
todosAxios.interceptors.request.use(requestLogger);
const responseLogger = response => {
console.log('received response', response);
return response;
};
todosAxios.interceptors.request.use(responseLogger);