TypeScript Promise

Learn via video courses
Topics Covered

Overview

The popularity of TypeScript for both frontend and backend web development is steadily expanding. TypeScript is intended for large-scale application development and transpiles to JavaScript. Existing JavaScript programmes are also valid TypeScript programmes since TypeScript is a superset of JavaScript. TypeScript can be used to create JavaScript apps that can be run on both the client and server sides too.

Introduction

The Promise class is present in many recent JavaScript engines and is readily polyfilled. The primary objective behind promises is to introduce synchronous error handling to Async / Callback programmes.

A Promise is a proxy for a value that is not always known at the time the promise is generated. It lets you correlate handlers with the ultimate success value or failure cause of asynchronous activity. This allows asynchronous methods to return values in the same way that synchronous methods do: instead of delivering the final value immediately, the asynchronous method returns a promise to give the value at some time in the future.

A Promise is in one of the following states:

  • pending: in its preliminary form, neither fulfilled nor rejected.
  • fulfilled: denotes that the operation was successfully finished.
  • rejected: indicates that the procedure was unsuccessful.

TypeScript Promises

In TypeScript, the promise is used to create asynchronous programming. When we need to handle numerous jobs at once, we may utilize the TypeScript promise. We can skip the ongoing action and go to the next line of code by using TypeScript promise. TypeScript Promise includes an asynchronous programming or parallel programming capability that allows a number of activities to be done concurrently at the same time. In the next section, we will go through the TypeScript promise in further depth for a better understanding.

A TypeScript promises is a Promise class instance (object) (constructor). We utilize the new Promise(executor) syntax to build a promise and pass an executor function as a parameter. This executor function allows us to manipulate the behavior of our promise resolution or rejection.

We may specify the data type of the value delivered when a TypeScript promise is fulfilled. Because the error returned by the TypeScript promises can take any form, TypeScript sets the default data type of the value returned when the promise is rejected to any.

Syntax

A promise, as previously explained, is utilized for parallel programming. It is a type of object that may be used in TypeScript programming. Let's take a closer look at its syntax for a better understanding;

As you can see from the syntax above, we are creating the object of promise with a new keyword. There are two arguments for this function: refuse and resolve. The callback function is also invoked. In the next part, we will look at its internal workings in greater depth and use it when programming.

A generic type declaration is used to annotate the promise's resolution value type. Essentially, you promise a type using the Promise function Object(), which has the form new Promise<Type>() and indicates the resolved value type of the promise. However, you may achieve the equivalent result by using the let p: Promise<Type> = new Promise() syntax.

As shown in the above example, the integer is a promise generated using the Promise function Object() that resolves after one second. Because this promise's resolved data type is number, the TypeScript compiler will not enable you to run resolve function with a value other than a value of type number number.

Since the promise's rejection value's default type is any, using the reject method with any value is allowed. This is TypeScript's default behaviour.

Creating a Typescript Promise

We start with a basic TypeScript promise like this:

I used the TypeScript promise function Object() in this Promise to accept numbers as the generic type for the Promise's resolve value. The promise function Object() accepts an executor callback, which the compiler will call with the following two arguments:

  • resolve — This is a function for resolving the promise.
  • reject — This is a function for rejecting the promise.

As a result, our commitment can either be fulfilled or denied. The resolve part is handled by .then, and the reject part is handled by .catch.

Callbacks are executed when we resolve a Promise. Otherwise, the Promise is refused, and the catch callbacks are executed.

Promise resolutions are simple to make:

Promise rejections, on the other hand, should be reserved for extraordinary circumstances. Rejecting a promise with a raw string is considered poor practice. When rejecting a TypeScript promise, always use the error function Object() new Error.

Subscribing to the fate of the Typescript promise

Using, you can subscribe to the TypeScript promise fate. then (if it is resolved) or.catch (if rejected).

Chain-ability of Typescript Promises

The then, catch, and finally procedures all implicitly return a promise. Any value returned by these callback methods, including undefined, is wrapped in a promise and returned. Unless you intentionally deliver a new promise from these methods that may fail, this implicit promise is resolved by default.

As a result, you may add then, catch, or finally methods to any prior then, catch, or finally method. If one of these methods returns an implicit promise, the type of the delivered value is the resolved value type of the implicit promise. Let's look at an example.

Output:

We updated the previous example by adding a second then method to the first. Because the first then method produces a string result, the implicit promise returned by this method will be resolved with a string value. As a result, the second then method will get a value argument of type string, as seen by the results.

Promise.resolve

The resolve static method of the Promise call delivers a promise that has previously been properly resolved with the value specified in the Promise.resolve(value) call. This is simpler than generating a new instance of the Promise call and adding logic to quickly resolve the promise.

Output:

As seen by the above findings, the Promise returned the promise. Because the value parameter is of the type number, the resolve(value) method always returns a number value instantly.

Promise.reject

The Promise.reject(error) function, like the Promise.resolve static method, always returns a rejected promise. The promise rejection value is derived from the error parameter, and its type is any.

Output:

Promise<never> is the kind of promise returned by the Promise.reject method since this promise never resolves, hence there is no promise resolution value. As a result, the type of value resolved by the promise is never, as never denotes a value that never happens.

Promise.all

In other cases, you must deal with several promises. Use the Promise.all static method to perform a callback function when all promises are properly resolved.

The Promise.all method accepts an array of promises (iterable specifically) and returns a new promise. When all promises v1, v2,... are successfully resolved, the returning promise pAll is resolved. This promise is resolved by an array value containing the promise resolution values v1, v2,... in the sequence in which they occur.

Output:

As shown in the above example, the Promise.all method is general and accepts the type of the value resolved by each promise passed to it. As you can see from the above result, providing a generic type is highly useful when we are using the resolved value of this collective promise. Promise class's static methods are mostly generic, as seen in the examples below.

plaintext comes with one caveat. It uses the fail-fast mechanism, which means that if any of the input promises v1, v2,... fail, vAll fails. It will not wait for other pending commitments to be fulfilled.

Promise.allSettled

The Promise.allsettled is identical to the promise.all in the static method. Except for Promise.all , It waits until all of the promises are fulfilled (which means until they are resolved or rejected). As a result, Promise returned the Promise. allSettled will never say no (but we have added a catch block in the below example anyway).

Working with potential. As you can see from the preceding programme and its outcome, allSettled can be a little daunting. To begin, when all promises are settled, the allSettle function provides a promise that resolves with an array of PromiseSettledResult<type> values. The type is obtained from the input promise's type. The PromiseSettledResult type is seen below.

TypeScript's standard library provides these kinds. When a promise is fulfilled, the allSettled method turns its value to the PromiseFulfilledResult shape, and when it fails, it converts it to the PromiseRejectedResult shape. As a result, when allSettled is resolved, it returns an array of objects, each of which has the PromiseFulfilledResult or PromiseRejectedResult interface.

We may use PromiseFulfilledResult as a discriminant in the switch/case guard since it is a union of PromiseFulfilledResult and PromiseRejectedResult that share the status attribute of literal data type.

Keywords for Async/Await

Writing promises in the traditional manner appears to be challenging. There is a lot of redundant boilerplate code. In most cases, you have a function that takes some parameters and returns a promise that either resolves or rejects with some useful data. Using the Promise function Object() to add a promise-generating method seems ugly at times.

The async keyword in JavaScript converts a standard function into one that yields a promise implicitly. This async function's return value will be changed to an implicit promise that resolves with this value. If this function throws an error, the returned promise is rejected along with the error message.

Let's look at how to create a Promise and utilize it in async await. This approach aids in the simplification of code within methods such as setTimeout.

Make a new file called types.ts in the src folder. First, we'll create a function named begin that accepts a callback and calls it with the setTimeout method.

This method may be used to execute a callback that reports some text to the console.

Run the following command to build this code:

$ tsc types.ts

This will result in the creation of a new file called types.js. You may use node to execute this file on the console.

$ node types.js

You'll note that the code now works precisely how we want it to. However, we can greatly simplify things by utilizing async await.

To use async await, we just need to write a Promise-based delay function.

This function accepts a number of milliseconds and returns a Promise that is resolved after that number of milliseconds using setTimeout.

Now, call beginAsync an async function. This method is quite similar to the begin function that we wrote before. Within this method, we will use await to halt code execution until the Promise is resolved and then call the callback with the time parameter.

We can see that it still acts the same way when we run it with node, but our code is considerably simpler.

How to Implement Promises in TypeScript?

As we know, the promise is utilized in TypeScript to allow parallel programming. When we wish to run a number of tasks at the same time, we utilize parallel programming. The promise is used to manage several concurrent calls. The key advantage of utilizing the promise is that we may go to the next line of code without having to execute the preceding line. This also aids us in improving the application's performance.

There is also support in some states. For a better understanding, we will look at the signature in depth, as well as the return type and the many states it allows. See the following;

1. new keyword

The 'new' keyword is used in the preceding line of code to create an instance of the promise. As we have already established, this is a TypeScript object. It also contains one inner function with two parameters named 'reject' and 'resolve.' We can pass a callback function within this function.

2. Return type The inner function has two arguments. If the function's response is successful, it will return 'resolve'; if the function's answer is unsuccessful, it will return 'reject'.

3. Typescript promise states Promise supports a variety of states. These states are used to determine the function's status. In the promise, we have three alternative states accessible;

  • reject: If the answer from the promise function fails, the state will be rejected.'
  • pending: If the response does not arrive and we are waiting for the outcome, the status will be 'pending.'
  • fulfilled: If the answer from the promise in TypeScript is successfully received, the state is 'fullfeed.'

We may also conduct and manage the success and error responses. We can only use 'reject' and ‘resolve' from the promise function for this. In this section, we will discuss how to handle success and failure in promises, as seen below.

How to Handle the Success and Error in Promise

Handle Error in the Promise

We can simply manage a promise's error response since we have to reject the parameter that we supply within the callback function. This rejected argument will handle the error by using the catch() block that is provided. See the example syntax below for a better understanding of its usage.

As you can see from the code above, we are calling refuse. This will handle the error and the exception using the catch block in the code below.

Handle Success in the Promise

We can also handle the promise function's success response. We can utilize resolve and a successful callback to do this. Let's look at one example of syntax for beginners to get a better understanding of the code;

We are calling the resolve function in the preceding lines of code; it will manage the success response as from the promise function in TypeScript.

Rules and Regulations for the Promise

  • This is used for asynchronous calls.
  • Remember that only tasks that are independent of one another can be called from. Otherwise, the data inconsistency problem would arise.
  • It is necessary to pass the inner function while utilizing it; else, an error will occur.

Conclusion

  • The promise is a very efficient method of writing asynchronous programming. It also resolved all issues that arose while dealing with callbacks.
  • We can simply do parallel programming in TypeScript by utilizing promises, which are very straightforward to read and comprehend.
  • The async keyword instructs the JavaScript compiler how to handle the function.
  • When the compiler encounters the await keyword within the same code, it stops.
  • It assumes that the expression following await returns a Promise and waits until the Promise is resolved or refused before proceeding.
  • We may run many jobs at the same time, which improves application speed. Asynchrony is the sole task that is not reliant on each other.