# Promises
Een Promise
is een ingebouwd Javascript object dat toelaat om asynchrone operaties af te handelen. Het is een alternatief voor callback functies. Promises bieden heel wat voordelen:
- Maakt de asynchrone code leesbaarder.
- Betere afhandeling van asynchrone operaties.
- Beter controle over de flow, asynchrone operaties kunnen in serie of parallel uitgevoerd worden.
- Eenvoudige afhandeling van fouten.
# Staat van een Promise
Een Promise kan zich in een van drie toestanden bevinden:
- Pending: De initiële toestand wanneer de operatie nog niet is voltooid.
- Fulfilled (In orde): De operatie is met succes voltooid.
- Rejected (Afgewezen): De operatie is mislukt.
# Promise aanmaken
Een Promise
wordt gemaakt met de Promise
-constructor, die een callback-functie accepteert. Deze callback-functie heeft standaard twee parameters, resolve en reject, die worden aangeroepen om de Promise te vervullen of af te wijzen.
- Als alles goed is gegaan, dan roepen we de
resolve()
functie aan.- In deze functie geven we meestal als argument data mee om daarmee verder aan de slag te gaan.
resolve(data)
- In deze functie geven we meestal als argument data mee om daarmee verder aan de slag te gaan.
- Is er iets misgegaan, dan roepen we de
reject()
functie aan.- In deze functie geven we meestal als argument de fout mee.
reject(error)
- In deze functie geven we meestal als argument de fout mee.
const myPromise = new Promise((resolve, reject) => {
// Asynchrone operatie
if (operatieIsSuccesvol) {
resolve("Succesvolle uitkomst");
} else {
reject("Fout tijdens de operatie");
}
});
2
3
4
5
6
7
8
Willen we een promise in een functie plaatsen, dan is het een goed idee om een promise te returnen.
function fetchData() {
return new Promise((resolve, reject) => {
setTimeout(() => {
const data = { name: "John", age: 30 };
resolve(data); // Gegevens zijn met succes opgehaald
// Of om afwijzing te simuleren: reject('Fout bij ophalen van gegevens');
}, 2000);
});
}
2
3
4
5
6
7
8
9
# Promise gebruiken
De methoden .then()
, .catch()
en finally()
worden gebruikt om te reageren op de uitkomst van een Promise.
.then()
wordt uitgevoerd wanneer de Promise is vervuld. (resolve(data)
geeft data door aanthen((data) => {})
).catch()
wordt uitgevoerd bij afwijzing.(reject(error)
geeft data door aancatch((error) => {})
)finally()
wordt sowieso uitgevoerd ongeacht of een belofte is vervuld of verworpen.
myPromise
.then((result) => {
console.log("Vervuld:", result);
})
.catch((error) => {
console.error("Afgewezen:", error);
})
.finally(() => {
console.log("Promise is voorbij.");
});
2
3
4
5
6
7
8
9
10
function fetchData() {
return new Promise((resolve, reject) => {
setTimeout(() => {
const data = { name: "John", age: 30 };
resolve(data); // Gegevens zijn met succes opgehaald
// Of om afwijzing te simuleren: reject('Fout bij ophalen van gegevens');
}, 2000);
});
}
// Gebruik van de Promise
fetchData()
.then((data) => {
console.log("Gegevens opgehaald:", data);
})
.catch((error) => {
console.error("Fout bij ophalen van gegevens:", error);
});
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

Voorbeeld
function createApp() {
// ...
}
promise
.then((success) => {
console.log(success);
createApp();
})
.catch((reason) => {
console.log(reason);
createApp();
});
2
3
4
5
6
7
8
9
10
11
12
13
promise
.then((success) => console.log(success))
.catch((reason) => console.log(reason))
.finally(() => createApp()); // Korter met finally!
2
3
4
# Chaining van promises
Promises kunnen worden geketend met meerdere .then()
-calls, wat bekend staat als “Promise chaining”. Dit helpt bij het sequentieel uitvoeren van asynchrone taken en zal een alternatief bieden voor de callback-hell.
asyncFunctionThatIsAPromise()
.then((result) => {
return anotherAsyncFunction(result);
})
.then((finalResult) => {
console.log("Laatste resultaat:", finalResult);
})
.catch((error) => {
console.error("Fout tijdens de keten:", error);
});
2
3
4
5
6
7
8
9
10
function getUserDetails(userId) {
return new Promise((resolve, reject) => {
// Simulatie van het ophalen van gebruikersgegevens
setTimeout(() => {
const user = { id: userId, name: "Alice" };
resolve(user);
}, 2000);
});
}
function getUserPosts(user) {
return new Promise((resolve, reject) => {
// Simulatie van het ophalen van gebruikersposts
setTimeout(() => {
const posts = ["Post 1", "Post 2"];
resolve({ user, posts });
}, 2000);
});
}
// Chaining van Promises
getUserDetails(123)
.then((user) => getUserPosts(user))
.then((result) => {
console.log("Gebruikersgegevens en posts:", result);
})
.catch((error) => {
console.error("Fout bij ophalen van gegevens:", error);
});
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# Parallel uitvoeren van promises
Promise.all()
: Wacht totdat alle Promises in een iterable zijn vervuld of er een wordt afgewezen.Promise.race()
: Wacht op de eerste Promise in een iterable die vervuld of afgewezen wordt.
# Promise.all()
Met Promise.all()
kunnen we wachten tot alle Promises
in een iterable zijn vervuld of er een wordt afgewezen.
const promise1 = asyncFunction1();
const promise2 = asyncFunction2();
Promise.all([promise1, promise2])
.then(([result1, result2]) => {
console.log("Alle promises zijn vervuld:", result1, result2);
})
.catch((error) => {
console.error("Ten minste één promise is afgewezen:", error);
});
2
3
4
5
6
7
8
9
10
const promise1 = fetchData("URL1");
const promise2 = fetchData("URL2");
Promise.all([promise1, promise2])
.then((results) => {
console.log("Alle data is opgehaald:", results);
})
.catch((error) => {
console.error("Fout bij ophalen van data:", error);
});
2
3
4
5
6
7
8
9
10
const a = () => new Promise((resolve) => setTimeout(() => resolve("a"), 2000));
const b = () => new Promise((resolve) => setTimeout(() => resolve("b"), 1000));
const c = () => new Promise((resolve) => setTimeout(() => resolve("c"), 1000));
const d = () => new Promise((resolve) => setTimeout(() => resolve("d"), 1000));
console.time("promise.all");
Promise.all([a(), b(), c(), d()])
.then((results) => console.log(`Done! ${results}`))
.catch(console.error)
.finally(() => console.timeEnd("promise.all"));
2
3
4
5
6
7
8
9
10
# Promise.race()
Met Promise.race()
wachten we op de eerste Promise
in een iterable die vervuld of afgewezen wordt.
const promise1 = fetchData("URL1");
const promise2 = fetchData("URL2");
Promise.race([promise1, promise2])
.then((winner) => {
console.log("De eerste die klaar is:", winner);
})
.catch((error) => {
console.error("Fout bij ophalen van data:", error);
});
2
3
4
5
6
7
8
9
10
const a = () => new Promise((resolve) => setTimeout(() => resolve("a"), 2000));
const b = () => new Promise((resolve) => setTimeout(() => resolve("b"), 1000));
const c = () => new Promise((resolve) => setTimeout(() => resolve("c"), 1000));
const d = () => new Promise((resolve) => setTimeout(() => resolve("d"), 1000));
console.time("promise.race");
Promise.race([a(), b(), c(), d()])
.then((results) => console.log(`Done! ${results}`))
.catch(console.error)
.finally(() => console.timeEnd("promise.race"));
2
3
4
5
6
7
8
9
10