# Out of the box programming in Javascript

In this article, we are going to explore the different behaviour of the javascript when there is no limit of the time and how the modern web application feels more realistic and user friendly and responsive.

## Asynchronous programming

In one of my article i discuss and make the difference between synchronous and asynchronous programming language. This article take you to journey on the asynchronous programming language.

**async/await** is a modern JavaScript syntax built on top of Promises that allows developers to write asynchronous code in a cleaner, synchronous-like style, making it easier to read, understand, and maintain. The `async` keyword declares a function that always returns a **Promise**, automatically wrapping non-promise values in a resolved Promise, while the `await` keyword pauses the function's execution until the awaited Promise is settled (resolved or rejected).

```javascript
async function fetchData(){
    // ===== fetching data ======
}
```

this is how you define a function with the help of the `async` keyword. where as `await` keyword is used where you are not sure the how much time does it take to execute

```javascript
async function fetchData(){
    const result = await database.call();
}

// In this example, you have no idea when did you get the data in result. 
```

> it is compulsory that you need to add async whenever you are using await keyword

Key characteristics include:

*   **Function Behavior**: An `async` function runs synchronously until it hits an `await` expression, at which point execution pauses without blocking the main thread, allowing the JavaScript engine to perform other tasks.
    
*   **Error Handling**: Unlike standard Promises that require `.catch()` chains, async/await enables the use of standard **try/catch** blocks to handle errors within the same logical flow.
    
*   **Usage Constraints**: The `await` keyword is **only valid** inside `async` functions (or top-level modules); using it elsewhere results in a `SyntaxError`.
    

## Error handling

In `async/await` programming, you always need to try-catch block because there are high chances the failure of the code while writing the async/await programming and try catch will eventually become handy as well as help in debugging your code whenever error is arise

To handle errors in **async/await** JavaScript, wrap the `await` expressions in a `try...catch` **block**. If the awaited promise rejects or throws an error, execution immediately jumps to the `catch` block, preventing the error from becoming an unhandled promise rejection.

**Basic Syntax**

```javascript
async function fetchData() {
  try {
    const response = await fetch('https://api.example.com/data');
    if (!response.ok) throw new Error(`HTTP error! Status: ${response.status}`);
    return await response.json();
  } catch (error) {
    console.error('Fetch error:', error.message);
    // Handle the error or re-throw
    throw error; 
  }
}
```

**Key Behavior and Edge Cases**

*   **Synchronous-like Flow**: Errors thrown inside the async function or rejected promises behave like synchronous exceptions, allowing standard `try...catch` logic.
    
*   **Scope**: The `try...catch` block only catches errors that occur within its own scope; errors from external callbacks (like `setTimeout`) are not caught unless the promise is explicitly rejected.
    
*   **Global Fallback**: If an error is not caught locally, the promise generated by the async function becomes rejected, requiring a `.catch()` handler on the function call or a global `window.onunhandledrejection` listener.
    
*   **Multiple Await Statements**: A single `try...catch` block can wrap multiple `await` lines; if any line fails, control jumps to the `catch` block immediately.
    

<table style="min-width: 75px;"><colgroup><col style="min-width: 25px;"><col style="min-width: 25px;"><col style="min-width: 25px;"></colgroup><tbody><tr><td colspan="1" rowspan="1"><p>Scenario</p></td><td colspan="1" rowspan="1"><p>Mechanism</p></td><td colspan="1" rowspan="1"><p>Result</p></td></tr><tr><td colspan="1" rowspan="1"><p><strong>Error in async function</strong></p></td><td colspan="1" rowspan="1"><p><code>try { await promise } catch (e)</code></p></td><td colspan="1" rowspan="1"><p>Catches the error.</p></td></tr><tr><td colspan="1" rowspan="1"><p><strong>Error in callback</strong></p></td><td colspan="1" rowspan="1"><p><code>setTimeout(() =&gt; throw e)</code></p></td><td colspan="1" rowspan="1"><p><strong>Not</strong> caught by <code>try...catch</code>; use <code>reject()</code>.</p></td></tr><tr><td colspan="1" rowspan="1"><p><strong>Unhandled Rejection</strong></p></td><td colspan="1" rowspan="1"><p>No <code>try...catch</code> or <code>.catch()</code></p></td><td colspan="1" rowspan="1"><p>Triggers <code>window.onunhandledrejection</code> event.</p></td></tr><tr><td colspan="1" rowspan="1"><p><strong>Re-throwing</strong></p></td><td colspan="1" rowspan="1"><p><code>throw error</code> inside <code>catch</code></p></td><td colspan="1" rowspan="1"><p>Propagates the error to the next caller.</p></td></tr></tbody></table>

**Alternative: Chaining** `.catch()` Instead of using `try...catch` inside the function, you can attach a `.catch()` directly to the async function call, though this is less convenient for handling errors within the function's logic.

```javascript
async function myFunc() {
  const data = await fetchData();
  return data;
}

// Handling error outside the function
myFunc()
  .then(data => console.log(data))
  .catch(err => console.error(err));
```

## Conclusion

Asynchronous programming is what makes modern JavaScript applications feel responsive and user-friendly. By allowing long-running tasks to execute without blocking the main thread, apps can remain interactive while fetching data, performing I/O, or handling timers.

The async/await syntax builds on Promises to provide a clearer, more synchronous-looking way to write asynchronous code. An `async` function always returns a Promise, and `await` pauses execution of that function until the awaited Promise settles—without freezing the UI. Paired with standard Promise patterns (like `Promise.all`) and proper error handling (try/catch or `.catch()`), async/await helps you write code that is easier to read, reason about, and maintain.

Start by refactoring callback-heavy code into Promises, then adopt async/await for clearer flow. Pay attention to error handling and consider patterns for concurrency and cancellation as your needs grow. With these tools and practices, you can build more robust, performant, and developer-friendly web applications.
