JavaScript Promises Explained Through Online Multiplayer Matchmaking đŽ

If youâve ever played an online multiplayer game, you already understand JavaScript Promises â even if you donât realize it yet.
You open the game, click âFind Matchâ, and then⌠you wait.
You donât instantly jump into the game. Instead, the system starts searching in the background â looking for players, checking servers, matching skill levels. While this is happening, youâre free to browse menus, customize your character, or even cancel the search. The game doesnât freeze.
This is exactly how JavaScript Promises work
A Promise represents a task that starts now but finishes later. JavaScript doesnât stop and wait for it. It continues running other code while the Promise quietly does its job in the background â just like matchmaking.
In JavaScript, a Promise represents the result of an asynchronous operation.
Promise States
From the moment matchmaking begins, it can move through three possible states:
1.Pending
Youâve clicked âFind Match.â
The search is on. Players are being matched, servers are checked, and the outcome is still unknown.
In JavaScript terms, the Promise has been created, but it hasnât completed yet.
2.Fulfilled
Success! đ
Enough players are found, the lobby fills up, and the match begins.
This is when a Promise completes successfully and returns the result you were waiting for.
3.Rejected
Something went wrong đ
Maybe the servers are down, the ping is too high, or there simply arenât enough players.
Here, the Promise fails and returns an error instead of a result.
Promise Creation
Creating a Promise in JavaScript is like clicking the âFind Matchâ button in a multiplayer game.At that moment, youâre not guaranteed a match â youâre only starting the process.
const findMatch = new Promise((resolve, reject) => {
const playersFound = true;
setTimeout(() => {
if (playersFound) {
resolve("Match found! Lobby is ready.");
} else {
reject("Matchmaking failed. No players available.");
}
}, 2000);
});
Whatâs happening here?
new Promise()â Player clicks Find Matchresolve()â Match successfully found.Marks the Promise as fulfilled.reject()â Matchmaking failed.Sometimes things go wrong â servers crash, players quit, or the queue is empty.Thatâs when
rejectis used.setTimeout()â Simulates waiting for players
At this point, the Promise is pending. JavaScript moves on, just like the game UI stays responsive while matchmaking runs.
Handling a Promise
Once matchmaking finishes, the game reacts differently depending on the outcome.
JavaScript does the same using .then() and .catch().
findMatch
.then((message) => {
console.log(message);
console.log("Loading game...");
})
.catch((error) => {
console.error(error);
console.log("Showing retry button...");
});
.then()runs only if the match is found..then()receives the value passed toresolve().It runs only when the Promise is fulfilled.catch()runs only if matchmaking fails..catch()receives the reason passed toreject().It runs **only when the Promise is rejected.**This is where you handle errors gracefully
Just like in a real game:
Match found â load the map
Match failed â show an error or retry option
Cleanup with .finally():
Some things happen regardless of success or failure â like stopping the loading animation.
findMatch
.finally(() => {
console.log("Stopping matchmaking animation");
});
.finally() runs every time, whether the Promise is fulfilled or rejected.
Promise Chaining
Real games donât stop at finding a match.
They load the map, sync players, and then start the game â step by step.
This is where Promise chaining comes in
function loadMap() {
return new Promise((resolve) => {
setTimeout(() => resolve("Map loaded"), 1000);
});
}
function startGame() {
return new Promise((resolve) => {
setTimeout(() => resolve("Game started"), 1000);
});
}
findMatch
.then((message) => {
console.log(message);
return loadMap();
})
.then((mapStatus) => {
console.log(mapStatus);
return startGame();
})
.then((gameStatus) => {
console.log(gameStatus);
})
.catch((error) => {
console.error("Error:", error);
});
What this represents in real life:
Find players
Load the game map
Start the match
Each step waits for the previous one to finish â no callbacks, no chaos.
Promise Static Methods: Handling Multiple Matchmaking Scenarios
In multiplayer games, youâre rarely dealing with just one thing at a time.
There are:
Multiple players joining
Multiple servers responding
Multiple checks happening in parallel
JavaScript handles these situations using Promise static methods â methods that live directly on the Promise object.
1.Promise.resolve() â Instant Success
Sometimes the game already has what it needs.
For example, youâre reconnecting to a match thatâs already active.
const instantMatch = Promise.resolve("Reconnected to ongoing match");
instantMatch.then((message) => {
console.log(message);
});
Real-life meaning:
Match already exists
No waiting needed
Promise is instantly fulfilled
Useful when you want to return a Promise without doing async work.
2.Promise.reject() â Instant Failure
Sometimes the game knows immediately that something wonât work.
For example, youâre banned or offline.
const instantFail = Promise.reject("Cannot join match: No internet");
instantFail.catch((error) => {
console.error(error);
});
Real-life meaning:
No matchmaking attempt needed
Promise is instantly rejected
3.Promise.all() â All Players Must Be Ready
A match can start only when everyone is ready.
Promise.all() waits for all Promises to succeed.
const player1 = Promise.resolve("Player 1 ready");
const player2 = Promise.resolve("Player 2 ready");
const player3 = Promise.resolve("Player 3 ready");
Promise.all([player1, player2, player3])
.then((players) => {
console.log("Match starting:", players);
})
.catch((error) => {
console.error("Match cancelled:", error);
});
Rules of Promise.all():
All Promises must resolve â
If one fails, everything fails â
Result is an array of resolved values
Perfect for loading assets, players, or configs together.
4.Promise.any() â First Server That Responds Wins
Games often ping multiple servers and connect to the first one that responds.
Thatâs exactly what Promise.any() does.
const server1 = new Promise((_, reject) =>
setTimeout(() => reject("Server 1 down"), 1000)
);
const server2 = new Promise((resolve) =>
setTimeout(() => resolve("Connected to Server 2"), 2000)
);
Promise.any([server1, server2])
.then((result) => {
console.log(result);
})
.catch((error) => {
console.error("All servers failed");
});
Rules of Promise.any():
Resolves as soon as one Promise succeeds
Ignores failures unless all fail
Great for fallback strategies
5.Promise.race() â Whoever Responds First (Win or Lose)
Sometimes the game just takes the first response, good or bad.
const fastServer = new Promise((resolve) =>
setTimeout(() => resolve("Fast server connected"), 1000)
);
const slowServer = new Promise((resolve) =>
setTimeout(() => resolve("Slow server connected"), 3000)
);
Promise.race([fastServer, slowServer])
.then((result) => {
console.log(result);
});
Rules of Promise.race():
First Promise to settle wins
Can be resolve or reject
Often used for timeouts
6.Promise.allSettled() â Check Everyoneâs Status
Sometimes you donât want to cancel the match â
you just want to know who is ready and who isnât.
const p1 = Promise.resolve("Player 1 ready");
const p2 = Promise.reject("Player 2 disconnected");
Promise.allSettled([p1, p2]).then((results) => {
console.log(results);
});
Output looks like:
[
{ status: "fulfilled", value: "Player 1 ready" },
{ status: "rejected", reason: "Player 2 disconnected" }
]
Useful for diagnostics and partial success handling.
Conclusion
At its core, JavaScript Promises arenât some abstract or complicated concept â theyâre just a way to deal with waiting.
Online multiplayer games have been solving this problem for years. When you click Find Match, the game doesnât freeze. It keeps running while something uncertain happens in the background. Eventually, the match either starts or it doesnât. And when that result arrives, the game reacts accordingly.
Thatâs exactly how Promises work.
States tell you where the process is
resolveandrejectdecide the outcome.then()and.catch()react to that outcomeChaining models real-world sequences
Static methods handle multiple async tasks at once
Once you see Promises this way, they stop feeling like âJavaScript magicâ and start feeling like common sense.
And the best part?
This same mental model scales â from loading a game lobby to fetching APIs, handling payments, uploading files, or syncing data in real-world applications.
So the next time youâre stuck on a matchmaking screen, waiting for players to join, remember:
youâre not just waiting â youâre watching a Promise in action.




