Promise in JavaScript. Code examples open

Promise in JavaScript. Code examples

In standard JavaScript execution, statements are executed sequentially, one after the other. That is, the first instruction is executed first, then the second, and so on.

If the operation takes a very long time, for example, we will perform a complex query to the database, which will last a long time. With sequential execution, all subsequent operations will wait for this operation.

A Promise is an object representing the success and failure of an asynchronous operation. An asynchronous operation, to put it simply, is some action that is performed regardless of the surrounding code in which it is called, does not block the execution of the called code.

A Promise can acquire the following states:

  • pending – initial state, promise created but not yet completed
  • fulfilled – the action that represents the promise completed successfully
  • rejected – an error occurred while performing the action that represents the promise

Creation

To create a promise, use the Promise constructor:

    new Promise(func)

func – a function that is executed when a promise is created. Typically, this function represents asynchronous operations that take a long time to complete.

For example, let’s define the simplest Promise:

    const myPromise = new Promise(function () {
        console.log("Performing an asynchronous operation");
    });

Here, the function simply prints a message to the console. Accordingly, when executing this code, we will see the message “Performing an asynchronous operation” on the console.
When a promise is created, when its function has not yet started executing, the promise goes into the “pending” state, that is, it is waiting for execution.

Typically, a function that is passed to the Promise constructor takes two parameters:

    const myPromise = new Promise(function (resolve, reject) {
        console.log("Performing an asynchronous operation");
    });

Both of these options – resolve and reject – also represent functions. And each of these functions takes a parameter of any type.

resolve – is called on success. We can pass a value into it, which we can get as a result of successful execution.
reject – is called if the operation completed with an error. We can pass a value to it that will provide some information about the error.

Successful fulfillment of the promise

The first function parameter in the Promise constructor – the resolve function is executed on success. This function is usually passed a value that represents the result of the operation if successful. This value can represent any object. For example, let’s pass the string to this function:

    const myPromise = new Promise(function (resolve) {
        console.log("Performing an asynchronous operation");
		resolve("Hello World");
    });
	 

The resolve() function is called at the end of the operation being performed, after all actions. When this function is called, the promise goes to the fulfilled state.

Passing Error Information

The second function parameter in the Promise constructor is the reject function to be called when an error occurs.This function is usually passed some error information, which any object can represent. For example:

const myPromise = new Promise(function(resolve, reject){
console.log("Performing an asynchronous operation");
reject("Incorrect data sent");
});

When calling the reject() function, the promise goes into the rejected state (ended with an error).

Logic using resolve and reject

    const x = 4;
    const y = 0;
    const myPromise = new Promise(function (resolve, reject) {

        if (y === 0) {
            reject("Incorrect data sended");
        }
        else {
            const z = x / y;
            resolve(z);
        }
    });

Getting the result of an operation in a Promise

Earlier, we looked at how we can pass the result of an asynchronous operation from the promise function to the outside:

    const myPromise = new Promise(function (resolve) {

        console.log("Performing an asynchronous operation:");
        resolve("Hello World");

    });

Now we get this value. The then() function of the Promise object is used to get the result of the promise operation:

    then(onFulfilled, onRejected);

onFulfilled – represents a function that is executed when a promise completes successfully. receives the data passed to resolve() as a parameter.

onRejected – represents a function that is executed when an error occurs and receives the data passed to reject() as a parameter.

The then() function also returns a Promise object.

So, we get the transferred data:

    const myPromise = new Promise(function (resolve) {
        console.log("Asynchronous operation");
        resolve("Hello World!");
    });
    myPromise.then(function (value) {
        console.log(value);
    })

The value parameter here will represent the string “Hello world!“, which is passed to resolve(“Hello world!”).

In this case, we do not have to pass any value to resolve() at all. Perhaps the asynchronous operation is simply executed and passes no result to the outside:

    const x = 4;
    const y = 8;
    const myPromise = new Promise(function () {
        console.log("Asynchronous operation");
        const z = x + y;
        console.log(`Operation result: ${z}`)
    });
    myPromise.then();

In this case, the function in the promise calculates the sum of the numbers x and y and prints the result to the console.

Promise.resolve

Sometimes you just need to return some value from a promise. To do this, you can use the Promise.resolve() method. The value returned from the promise is passed to this method.

The Promise.resolve() method returns a Promise object:

    const myPromise = Promise.resolve("Hello World");

    myPromise.then(value => console.log(value));     //Hello World

Defining a promise through a function

Often a promise is defined through a function that returns a Promise object. For example:

    function sum(x, y) {
        return new Promise(function (resolve) {
            const result = x + y;
            resolve(result);
        })
    }
    sum(3, 5).then(function (value) { console.log("Operation result:", value); });
    sum(25, 4).then(function (value) { console.log("Sum of numbers:", value); });

Here the sum() function takes two numbers and returns a promise that encapsulates the sum of those numbers.

After the calculation, the sum of the numbers is passed to resolve(), respectively, we can then get it through the then() method.

Defining a promise through a function allows us, on the one hand, to pass different values when calling the function. And on the other hand, work with the result of this function as a promise and configure the processing of the received value for each specific call.

However, what if we have the same principle of processing the value received from the asynchronous function?

    sum(3, 5).then(function (value) { console.log(value); });
    sum(25, 4).then(function (value) { console.log(value); });

In this case, the processing logic will be repeated. But since the then() method also returns a Promise object, we can do something like this:

    function sum(x, y) {
        return new Promise(function (resolve) {
            const result = x + y;
            resolve(result);
        }).then(function (value) { console.log("Operation result:", value); });
    }
    sum(3, 5);
    sum(25, 4);

Flexible function settings

But what if we want the programmer to have a choice: if he wants, he can define his own handler, and if not, then some default handler is applied. In this case, we can define a handler function as a function parameter, and if it is not passed, then set the default handler:

    function sum(x, y, func) {
        // if the handler is not installed, then install the default handler
        if (func === undefined) func = function (value) { console.log("Operation result:", value); };

        return new Promise(function (resolve) {
            const result = x + y;
            resolve(result);
        }).then(func);
    }
    sum(3, 5);
    sum(25, 4, function (value) { console.log("Summ:", value); });

Here, the first time the function sum() (sum(3, 5)) is called, the default handler will be triggered. In the second case, the handler is explicitly passed through the third parameter, so it will be used sum(25, 4, function(value){console.log(“Amount:”, value);})

Error processing

One of the benefits of promises is easier error handling. To receive and handle an error, we can use the catch() function of the Promise object, which takes an error handler function as a parameter:

    const myPromise = new Promise(function (resolve, reject) {
        console.log("Asynchronous operation");
        reject("Incorrect data sent");
    });
    myPromise.catch(function (error) {
        console.log(error);
    });

The catch() function takes an error handler as a parameter. The parameter of this handler function is the value that is passed to reject().

Error Generation

Above, the reject() function was called to notify of an error. But it is worth noting that an error can occur without calling the reject() function.
!And if an error is generated in the operation performed in the promise for one reason or another, then the entire operation also ends with an error.

    const myPromise = new Promise(function (resolve) {
        console.log("Asynchronous operation");
        someFunction();      // calling a non-existent function
        resolve("Hello world!");
    });

    myPromise.catch(function (error) {
        console.log(error);
    });

Since the function someFunction() is not declared anywhere, the execution of an asynchronous task will fail with an error. Therefore, the error handling function from catch() will work, which, through the error parameter, will receive information about the error that has occurred, and we will see an error message in the browser console.

throw

Also, an error can be the result of a call to the

Throw in JavaScript. Code examples open
Throw in JavaScript. Code examples
September 6, 2022
Roman-tk
operator, which generates an error:

    const myPromise = new Promise(function (resolve, reject) {
        console.log("Performing an asynchronous operation");
        const parsed = parseInt("Hello");
        if (isNaN(parsed)) {
            throw "Not a number";
        }
        resolve(parsed);
    });
    myPromise.catch(function (error) {
        console.log(error);
    });

If the parsing result does not represent a number, then using the throw statement, we generate an error. This will come to the end of the whole function with an error. And in the end, the result will be processed by the catch function.

This situation may seem artificial, since it makes no sense for us to throw an error in the code above with throw, since in this case we can also pass an error message to the reject function:

    if (isNaN(parsed)) {
        reject("Not a number");
    }

However, this operator can be used in an external function that we call in the code:

    function getNumber(str) {
        const parsed = parseInt(str);
        if (isNaN(parsed)) throw "Not a number";            // Generating an error
        else return parsed;
    }
    const myPromise = new Promise(function (resolve) {
        console.log("Performing an asynchronous operation");
        const result = getNumber("hello");
        resolve(result);
    });
    myPromise.catch(function (error) {
        console.log(error);
    });

Here, the parsing of a string into a number is moved to an external function – getNumber, however, when this function is called in a promise, an error will also occur from the throw operator.

try..catch

As in the general case, operations that can generate an error can be placed in a try..catch construct, and if an exception occurs in the catch block, call the reject() function:

    const myPromise = new Promise(function (resolve, reject) {
        try {
            console.log("asynchronous operatio");
            getSomeWork();      // calling a non-existent function
            resolve("Hello world!");
        }
        catch (err) {
            reject(`Error : ${err.message}`);
        }
    });
    myPromise.catch(function (error) {
        console.log(error);
    });

Handling an error with the then function

In addition to the catch function, you can also use the then() function to get information about the error and handle it. Second parameter is an error handler, which receives as a parameter passed from the reject function meaning:

    promise
        .then(function (value) {
            // get value
        },
            function (error) {
                // error handling
            });

The second parameter of the then() function represents the error handler function. Using the error parameter in the handler function
we can get the value passed to reject(), or information about the error that occurred.

Example:

    function generateNumber(str) {
        return new Promise(function (resolve, reject) {
            const parsed = parseInt(str);
            if (isNaN(parsed)) reject("value is not a number")
            else resolve(parsed);
        })
            .then(function (value) { console.log(value); },
                function (error) { console.log("Возникла ошибка:", error); });
    }

    generateNumber("23");
    generateNumber("hello");
0

More

Leave a Reply

Your email address will not be published. Required fields are marked *

How many?: 22 + 22

lil-code© | 2022 - 2024
Go Top
Authorization
*
*
Registration
*
*
*
*
Password generation