Doing an asynchronous HTTP request - what's the difference between these two?
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Introduction
When two HTTP request examples both look asynchronous, the important difference is usually not the network call itself. The real distinction is how completion is represented, when later code continues, and how errors move through the program.
Both can be asynchronous at the transport level
An HTTP request is asynchronous when the program starts the request and continues running other code while the response is in flight. In JavaScript, both promise-based and async and await code can do that.
For example, these both start an asynchronous request:
The network activity is still non-blocking in both versions. The difference is the style of control flow, not whether the socket suddenly behaves differently.
Promise chaining versus async and await
A promise-based version returns a promise to the caller:
An async function also returns a promise, but it lets you write the steps in a top-to-bottom style:
Under the hood, both versions are asynchronous. The main benefit of async and await is readability, especially when several dependent requests must happen in sequence.
Fire-and-forget versus awaited completion
Another major difference between two async request styles is whether the caller actually waits for the result.
Fire-and-forget:
Awaited:
Both requests are asynchronous, but the second form makes later code depend on successful completion. That is a real behavioral difference even though neither one blocks the JavaScript event loop the way a synchronous network API would.
Error propagation is often the real difference
Different async styles can make errors feel very different.
Promise chain:
async and await:
This matters because people often compare two snippets and think the syntax is the whole story. In practice, how each version handles failure, retries, cleanup, and dependent work is often the more important difference.
Sequential versus concurrent async requests
Two HTTP request patterns may both be asynchronous but still differ in whether they run sequentially or concurrently.
Sequential:
Concurrent:
Both use asynchronous HTTP requests, but the second version allows both requests to progress at the same time. If the data does not depend on one another, concurrency is often the better design.
A request can be asynchronous while your code still behaves badly
One source of confusion is that using an asynchronous API does not automatically produce good async structure. For example, if you start a request but forget to return or await the promise, outer code may continue too early.
This function returns before the request result is used. The request is still asynchronous, but the program logic is wrong.
Correct version:
Common Pitfalls
The biggest mistake is thinking await makes an HTTP request synchronous. It does not. It only pauses that async function while the event loop continues handling other work.
Another issue is forgetting that parsing the body can also be asynchronous. In the Fetch API, response.json() returns a promise too, so awaiting the request alone is not enough if you still need the parsed payload.
Developers also start requests without returning or awaiting the promise when later code depends on the result. That creates race conditions that can look like "async is broken" when the real problem is control flow.
Finally, do not compare two request snippets only by syntax. Check whether they differ in sequencing, concurrency, error propagation, or whether the caller actually waits for completion.
Summary
- Two HTTP request snippets can both be asynchronous while still behaving differently.
- Promise chains and
asyncandawaitmainly differ in how completion and errors are expressed. - Fire-and-forget and awaited requests have different downstream behavior.
- Sequential async code and concurrent async code are not the same thing.
- The important comparison is usually control flow and error handling, not whether the HTTP transport is "really async."
Related reading
- dotnet core app api do not keep running on kubernetes
- DownloadStringAsync wait for request completion
- Duplicate ID, tag null, or parent id with another fragment for com.google.android.gms.maps.MapFragment
- DynamoDB API How can I build an add JSON attribute if not present update request?
- Double Checked Locking in Singleton
- Dynamic periodic tasks - alternatives to Celery beat
- Easiest way to post to a server on iPhone? I don't care about the response
- EC2 instance has no public DNS

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.