Mastering the art of Promises and handling errors

I've been tasked with developing a WebApp using Angular, but I'm facing a challenge as the project involves Typescript and asynchronous programming, which are new to me. The prototype already exists, and it includes a handshake process that consists of calculations and HTTP requests. All functions, even those performing calculations, return a Promise that resolves or rejects based on the outcome.

The functions are connected in a long chain using .then, handling errors along the way. However, this implementation seems complex, and I'm unsure about what's happening behind the scenes:

this.startHandshake()
  .then((buf) => this.calculateSomthing(buf)
    .then((buf2) => http.sendData(buf2)
       ..., // this goes on many levels
    (e:Error) => this.handleError(e)),
  (e:Error) => this.handleError(e))
.catch((e: Error) => { /* Error Handling */ });

My questions are:

  1. Is this coding pattern common for similar problems?
  2. I've heard that Promises are executed in a single-threaded manner. What does this mean for Promises involving only calculations? When does the function within the Promise execute - immediately, queued until the original code finishes, or scheduled by the JavaScript engine?
  3. I'm thinking of writing some functions synchronously but need a way to handle errors. Using exceptions doesn't seem compatible with Promises.
  4. Would using async/await make the code more readable in my case? How would error handling work with async/await, and can it be combined with exceptions?

Answer №1

Perhaps delving deeper into the concept of promises and how to effectively utilize them would be beneficial for you. Nonetheless, here are answers to your questions:

this.startHandshake()
      .then((buf) => this.calculateSomthing(buf))
      .then((buf2) => http.sendData(buf2))
      .then(() => {all the reset} )
      .catch((e: Error) => { ... });
  1. In general, it is advisable to keep the promises chained one after another rather than nesting them inside each other. Therefore, your code should look something like this:

  2. The actions performed within the promise are synchronous, while those between the promises are asynchronous.

  3. As mentioned earlier, synchronized code can be placed inside the promise. When it comes to error handling, familiarize yourself with Promise.reject, which allows manual rejection of the promise.

  4. Async/await functions similarly to Promises but offers a more streamlined syntax. Personally, I prefer using async/await, although setting up the project may require additional attention (Promises are supported by most browsers, whereas async/await may not be).

Edit: There seems to be an issue with the code formatting below, so I have moved it up above the questions.

Best of luck!

Answer №2

Exploring the concept of callback hell can provide valuable strategies for resolving nested code complexities.

Answer №3

Imagine you have numerous functions, each returning a Promise

f1(p1: any):Promise<any> {}
f2(p2: any):Promise<any> {}
f3(p3: any):Promise<any> {}

If you wish to chain these functions and execute them one after the other, the best method (in my opinion) is to write something like this

const p1 = {} // my first parameter
f1(p1).then((result)=>f2(result))

Your code will be executed once you call the then method

To handle errors from all the methods used, you should utilize the catch method after the call to then

f1(p1).then((result)=>f2(result)).catch((err:Error)=>{ /** do something*/ })

In case you want to manage specific errors coming from one of your functions, I suggest doing something like this

 f1(p1).then((result)=>f2(result).catch((err)=>Promise.resolve(optionalResult))).catch((err:Error)=>{ /** do something*/ })

This process won't break your chain and will continue with the rest of the methods

Another option is to execute promises in parallel using the Promise.all() method as shown below

Promise.all([f1(p1), f2(p2), f3(p3)]).then((results:any[])=>{ ...})

This function will return an array with all the results

If you want to throw an error or stop the chain, you can use the Promise.reject method

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Retrieve the row id from the table by clicking on a button in a modal box using jQuery

I am encountering a challenge with a small task due to my limited experience in jQuery. I have a table where each row has an icon. When the icon is clicked, a modal box appears with some content. After closing the modal box, I want to retrieve the table ro ...

What is the proper way to retrieve the JSON data?

How can I retrieve data from another table to use in a detail view if the value returned by the getData method is null? <th data-field="id" data-detail-formatter="DetailFormatter">ID</th> <th data-field="prefix&quo ...

Issue with React Hook Form - frequent failure in submitting the form

I have implemented the useForm hook from https://www.npmjs.com/package/react-hook-form. However, I am encountering some inconsistent behavior where it sometimes works immediately, sometimes requires a page refresh to work, and sometimes doesn't work a ...

Hide the previous dropdown content in Vue JS by manipulating the visibility of the elements

I'm currently working on creating a Dropdown feature, but I'm facing an issue with hiding the dropdown content when another dropdown is clicked. <template> <div class="dropdown-container"> <div v-for="(it ...

Localhost Firebase authentication with Facebook integration

I am currently working on a Vue.js app that integrates Firebase for authentication, specifically with the Facebook provider. Despite configuring my Firebase code correctly, I continue to encounter the "Can't load URL: The domain of this URL isn't ...

Request with missing authentication header in Swagger OpenAPI 3.0

When generating the swagger.json using tsoa for TypeScript, I encountered an issue. Even after adding an access token to the authorize menu in Swagger and making a request to one of my endpoints, the x-access-token header is missing from the request. What ...

The table is not properly displaying the data even though it is stored in the array and can be seen in the browser console. What could be causing this issue with my

<tr *ngFor="let animal of readAnimal"> <th scope="row">{{ animal.id }}</th> <td>{{ animal.name }}</td> <td>{{ animal.description }}</td> <td>{{ animal.creat ...

Ways to include "working hours" if statement a particular holiday dates are specified

Trying to update the code for an "if statement" to include specific dates that are official holidays when the business is not operational. The current code works if the day falls on Mon, Tue, Wed, Thu, or Fri and the time is between 09:00 and 15:00 in a 24 ...

I prefer not to have the entire URL visible to me

function updateDate(day, month, year) { month += ""; if (month.length <= 1) month = "0" + month; document.location.href = "<?php $_SERVER['PHP_SELF'];?>?page=events&day=" + day + "&month=" + m ...

Angular2 encountering a lack of service provider issue

After finding the code snippet from a question on Stack Overflow titled Angular2 access global service without including it in every constructor, I have made some modifications to it: @Injectable() export class ApiService { constructor(public http: Http ...

"Embedding PHP code within HTML tags, which is then embedded within

Running into an issue within a while loop... echo 'var contentString = '<div id="content" > <div id="bodyContent"> <p>' + $row[name]+ '</p> ...

Include a sub-component N times within the main component, depending on the current state value

I need assistance in adding a child component called ColorBox to the parent component named ColorBoxContainer based on the value stored in state as noOfBoxes: 16. I've tried using a for-loop but it seems like my code is incorrect. Can someone guide me ...

How do I specify the default checked value for a checkbox in Redux Form?

Within our Redux Form 5.3 application (not version 6.x), the goal is to display an <input type="checkbox" /> in this manner: // Sometimes, fieldHelper.checked starts off as undefined. When a checkbox is // clicked by the user, fieldHelper.checked is ...

Having trouble accessing the root route in production environment

After creating a basic Node application with 5 routes that serve different HTML documents, I encountered an issue. While all the routes function properly when running on localhost, in production my root route displays a 404 error page, indicating that the ...

Tips for avoiding problems with quoting and using apostrophes in a JavaScript function inside a tag in a JSP file

Within my JSP, I have a string value stored in ${state.status.code} that I need to pass to a JavaScript function when a table element is clicked using onClick to trigger the showStatus function. Here is how I have attempted to achieve this: <c:set var= ...

Triggering a Bootstrap 5 dropdown through code is only effective within the browser's developer console, rather than standard JavaScript implementation

I attempted to display a Bootstrap5 dropdown by clicking on a link in my web application. Despite trying various methods, such as dispatching events and utilizing the bootstrap Dropdown classes, I was unable to achieve success. Interestingly, both approach ...

Can the script be loaded into a TypeScript file?

I'm currently in the process of integrating this script tag into my Angular 2 project, but I'm searching for a way to incorporate it into the typescript file so that I can access its methods within the .ts file. <script type="text/javascript" ...

Checking if an instance belongs to a specific class using a custom type guard in TypeScript

After successfully implementing the function isInstanceOfClass, which determines if an instance is of a given class, I am now faced with the task of writing the correct typing for it. class Parent { isInstanceOfClass<T>(arg: T): this is T { ...

Running Ng serve is not functioning properly with no indications of errors or messages to identify the issue

Recently, after updating to MacOS Sonoma, I encountered an issue where the ng serve command stopped working. While ng version is still functional and displays the current version, running ng serve in my project doesn't yield any results. The terminal ...

Tips for waiting on image loading in canvas

My challenge involves interacting with the image loaded on a canvas. However, I am uncertain about how to handle waiting for the image to load before starting interactions with it in canvas tests. Using driver.sleep() is not a reliable solution. Here is ...