Async JavaScript
Mastering Promises and Async/Await in React Native
Async JavaScript in React Native
Mobile apps are inherently asynchronous. Network requests, reading files, getting location, or waiting for user interaction all take time.
In mobileLauncherStandard, we handle this using Promises and Async/Await.
The Old Way vs The New Way
❌ Callbacks (Do not use)
getData(function(a) {
getMoreData(a, function(b) {
// Callback Hell
});
});✅ Async/Await (Our Standard)
We use async/await for cleaner, readable code that looks synchronous.
Real World Example: Authentication
Let's look at src/features/auth/services/auth.service.ts. This service handles logging users in, which requires talking to Supabase (network request) and saving tokens to device storage (disk I/O).
// src/features/auth/services/auth.service.ts
// 1. Mark function as 'async'
async signIn(credentials: LoginCredentials) {
try {
// 2. 'await' the network request
// The code PAUSES here until Supabase responds
const { data, error } = await supabase.auth.signInWithPassword({
email: credentials.email,
password: credentials.password,
});
if (error) throw error;
// 3. 'await' the disk write
// We pause again to ensure tokens are saved before returning
await this.saveTokens(tokens);
return { success: true, user };
} catch (error) {
// 4. Handle errors centrally
logger.error("Sign in error", error);
return { success: false, error: error.message };
}
}Key Concepts
1. The async keyword
Declares that a function returns a Promise. Even if you return true, it actually returns Promise<true>.
2. The await keyword
- Can only be used inside an
asyncfunction. - It pauses execution until the Promise resolves.
- It unwraps the Promise result (e.g.,
const data = await promise).
3. Error Handling (try/catch)
Always wrap async code in try/catch blocks. If a network request fails, it "throws" an error that you must catch, otherwise your app might crash (or leave the user stuck in a loading state).
Common Pitfalls
"Forgetting to await"
// ❌ WRONG
const user = supabase.auth.getUser();
console.log(user); // Logs: Promise { <pending> }
// ✅ RIGHT
const user = await supabase.auth.getUser();
console.log(user); // Logs: User object"ForEach with Async"
Array.forEach does NOT wait for promises.
// ❌ WRONG - This will not wait!
items.forEach(async (item) => {
await saveItem(item);
});
console.log('Done'); // Prints "Done" before items are saved
// ✅ RIGHT - Use map + Promise.all
const promises = items.map(item => saveItem(item));
await Promise.all(promises);
console.log('Done');Interactive Practice
[!TIP] Go to StackBlitz and try writing a function that fetches data from
https://jsonplaceholder.typicode.com/todos/1.
// Copy this to StackBlitz
async function fetchTodo() {
try {
const response = await fetch('https://jsonplaceholder.typicode.com/todos/1');
const json = await response.json();
console.log(json);
} catch (e) {
console.error(e);
}
}
fetchTodo();