Angular
TypeScript
Sequential Execution
Functions
Angular 2/4

How to run functions sequentially in Angular 2/4 Typescript

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Running functions sequentially in Angular matters only when the work is asynchronous. If the functions are synchronous, JavaScript already runs them in order. The real problem appears when each step involves a promise, an HTTP request, or an observable that must finish before the next step starts.

Sequential Execution with async and await

If your functions return promises, async and await make sequence explicit and readable.

typescript
1async loadUser(): Promise<{ id: number; name: string }> {
2  return { id: 7, name: 'Ava' };
3}
4
5async loadPermissions(userId: number): Promise<string[]> {
6  return ['read', 'write'];
7}
8
9async saveAudit(userId: number): Promise<void> {
10  console.log('audit saved for', userId);
11}
12
13async runSequence(): Promise<void> {
14  const user = await this.loadUser();
15  const permissions = await this.loadPermissions(user.id);
16  await this.saveAudit(user.id);
17
18  console.log(user, permissions);
19}

Each await pauses the sequence until that promise settles. That is what forces true ordering.

Sequential Execution with RxJS

Angular code often works with observables instead of promises, especially for HTTP calls. In that case, concatMap is the usual operator for strict sequencing because it waits for one inner observable to complete before subscribing to the next one.

typescript
1this.userService.getUser().pipe(
2  concatMap(user => {
3    console.log('user loaded', user);
4    return this.permissionService.getPermissions(user.id);
5  }),
6  concatMap(permissions => {
7    console.log('permissions loaded', permissions);
8    return this.auditService.saveAudit();
9  })
10).subscribe({
11  next: () => console.log('all steps completed'),
12  error: err => console.error(err)
13});

This is the observable equivalent of an ordered promise chain.

Do Not Start Work Too Early

A common mistake is to create several async operations first and only await them later:

typescript
1const a = this.loadUser();
2const b = this.loadPermissions(7);
3
4await a;
5await b;

This does not enforce true sequence because both operations were started before either await. If the second task depends on the first, create it only after the first one finishes.

Error Handling Belongs in the Same Flow

Sequential workflows are easier to reason about when failures stop the chain clearly. With promises, wrap the sequence in try and catch. With observables, handle the error in subscribe or with an operator such as catchError.

That prevents later steps from running against incomplete state or partial data.

Pick the Pattern That Matches the Codebase

If the code already returns promises, use async and await. If the code already uses RxJS heavily, staying inside the observable pipeline is often cleaner than converting everything to promises just for sequencing.

The important choice is not Angular version. The important choice is which async abstraction your code already uses and how much control you need over cancellation, composition, and subscription lifetime.

Synchronous Functions Need No Async Tooling

If the functions are ordinary synchronous methods, just call them in order:

typescript
firstStep();
secondStep();
thirdStep();

Adding promises or observables to purely synchronous code only makes the control flow harder to read.

Common Pitfalls

Assuming normal function order is enough when the real work is asynchronous causes race conditions.

Starting multiple async operations first and then awaiting them later defeats true sequential execution.

Using mergeMap when strict ordering is required allows concurrency when you did not want it.

Mixing promises and observables carelessly can make execution order and error flow hard to follow.

Adding async abstractions to synchronous code is unnecessary complexity.

Summary

  • Sequential execution matters when the functions are asynchronous, not when they are plain synchronous calls.
  • Use async and await for promise-based workflows.
  • Use concatMap for observable-based workflows in Angular.
  • Create the next async step only after the previous one finishes if order matters.
  • Keep error handling inside the same control flow so failed steps stop the sequence cleanly.

Course illustration
Course illustration

All Rights Reserved.