What is the reason behind the lack of preservation of object state when using Promises?

Here is a code snippet to consider:

class ClientWrapper {
    private client: Client;

    constructor() {
        this.client = new Client();
    }

    async connect() : Promise<void> {
        return this.client.connect();
    }

    async isConnected(): Promise<boolean> {
        return this.client.isConnected();
    }
};

class Client {
    private data?: string;
    private connected: boolean;

    constructor() {
        this.connected = false;
    }

    isConnected(): boolean {
        return this.connected;
    }
    
    async connect() : Promise<void> {
        this.data = 'data';
        const res = await this.executeRequest();
        this.connected = true;
    }

    async executeRequest() : Promise<string> {
        return await Promise.resolve(this.data!);
    }
};

let wrapper = new ClientWrapper();
(async () => {
    await wrapper.connect();
    console.log(await wrapper.isConnected());
})();

At line 48, the output of

console.log(await wrapper.isConnected())
is true.

Now, if we change the connect() method in ClientWrapper to:

async connect() : Promise<void> {
    this.client.connect();
}

, where the return statement is removed.

After this modification, line 48 now outputs false.

The question then arises - why does the connected property of the Client class not retain the value of true? Does the absence of the return statement in the Promise<void> matter for this behavior?

Thank you!

Answer №1

The problem lies in the fact that you are invoking Client.connect() without using an await keyword. As a result, the asynchronous function Client.connect() gets executed while the function ClientWrapper.connect() has already completed its execution. To fix this issue, make sure to include the await keyword when calling the method:

await this.client.connect();

By adding the await keyword, the code will behave as expected.

Answer №2

Returning a Promise from an async function causes it to be merged into the main Promise returned by the function.

By using `await` on the wrapper.connect call, you were essentially awaiting the internal this.client.connect call.

When the return statement was removed, the wrapper.connect call was not synchronized with the inner this.client.connect call. It was like a fire-and-forget action within the function.

An alternative could be to replace the return statement with `await this.client.connect()` which would produce the same outcome and be more logical.

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

How can one trigger a service method in nestjs through a command?

I am looking to run a service method without relying on API REST - I need to be able to execute it with just one command ...

What is the best way to find all the corners along a path?

I am working with an SVG path and I need to find all the extremum points (corners) on this path. How can I achieve this? I attempted to retrieve all points using the following code: let totalLength = path.getTotalLength(); for (var i = 0; i < totalL ...

"Vue3 offers the ability to return a multi-layer object through the Provide-Inject

While implementing provide-inject in my personal project, I encountered an issue where the value returned by inject() was a RefImpl Object. This meant that I had to access the actual value using inject().value.value instead of just inject().value. Here is ...

Having trouble declaring custom pipes in Angular

A new pipe named 'shortend.pipe.ts' has been created within the app folder. import { PipeTransform } from "@angular/core"; export class ShortendPipe implements PipeTransform { transform(value: any, ...args: any[]) { return ...

What is the best way to utilize a tsconfig "alias path" to import an @ngModule along with other definitions?

Repository Link: https://github.com/andreElrico/mono-repo-test Stackblitz Example: https://stackblitz.com/github/andreElrico/mono-repo-test (noop; only to navigate smoothly) Assume the structure below: root/ ├── projects/ │ ├── app1 │ ...

Leveraging NPM workspaces in combination with Expo and Typescript

I'm struggling to incorporate NPM 7 workspaces into a Typescript Expo project. The goal is to maintain the standard Expo structure, with the root App.tsx file, while segregating certain code sections into workspaces. I'm facing challenges compil ...

Successful jQuery Ajax request made without the need for JSON parsing

I find it strange that my experience with jQuery's ajax function is completely different from what I'm used to. Below is the javascript code in question: $.ajax({ url: "/myService.svc/DoAction", type: "GET", dataType: "json", su ...

Can JavaScript be utilized to retrieve the MAC address?

Is it possible to retrieve the Mac addresses of a system for login using JavaScript? ...

"Interactive Connect 4 Game in Javascript - Drop the disk into the bottom row of the chosen

Check out this awesome Connect4 game I found: http://codepen.io/anon/pen/lmFJf I have a specific goal in mind for the game. When I click on an empty space in any column, I want it to automatically drop into the lowest available spot in that column, follow ...

The ng-click event is not triggering the Controller Function as expected

This is the Code for My View <div ng-controller="signupCtrl"> <ul class="list-group" > <li class="list-group-item"> <div class="form-group"> <input type="text" ng-model="signupCtrl.firstName"> ...

Obtain the Name of a Function in a TypeScript Class

Is it possible to access the method/function name within a TypeScript class? In the TypeScript snippet below, the intention is to display both the class name and the method name while the code is running. The class name can be obtained using this.construc ...

Encountering the error "No exported member 'RouteComponentProps' in the 'react-router-dom' module while upgrading to react-router v6"

We are currently in the process of migrating legacy class-based code to the latest version 6 of react router. However, we are encountering the following error during the migration: Module '"react-router-dom"' has no exported member &a ...

Ways to organize backbone models, views, and collections using vim?

I am a fan of vim's folding feature, but I have encountered some challenges when trying to fold backbone models, views, and collections. This is because backbone does not follow the traditional prototype syntax, but instead uses a .extend() based synt ...

What is the best way to retrieve the parent div's ID with JavaScript and Selenium?

My current project involves utilizing webdriverjs, and I am faced with the challenge of retrieving the parent id of a specific webelement among multiple elements with similar classes. Each element has a different id that gets dynamically generated when a m ...

Is it possible to compile TypeScript modules directly into native code within the JavaScript data file?

I am seeking a way to break down an app in a TypeScript development environment into separate function files, where each file contains only one function. I want to achieve this using TS modules, but I do not want these modules to be imported at runtime in ...

Assistance needed for JavaScript link substitution

As I am wrapping up the web application version of my website, I have encountered a small issue. I need to convert the <script> var a=document.getElementsByTagName("a"); for(var i=0;i<a.length;i++) { a[i].onclick=functio ...

Stop the page from scrolling when scrolling within a specific DIV to address the [Violation] warning appearing in the console

Initially, it may seem like a duplicate question that has been answered here, but there are additional aspects that need to be addressed. How do I resolve the following [Violation] warning in the Google Chrome console? [Violation] Added non-passive eve ...

Accessing content from a different HTML document

I'm currently working on a project using node.js where I need to take input from a text box in an HTML file and store it in an array. However, I'm struggling with how to achieve this. My ultimate aim is to create a chat application, and I believe ...

Issue with Bootstrap side navbar not collapsing when clicked on a link

Currently, I'm working on creating a website for a friend. While I used to have some experience with coding in the past, it has been a while and I am a bit rusty. This time around, I decided to use bootstrap for the project. However, I'm struggli ...

Error with object props in React using Typescript

Here's a scenario; I have a list of 'Reviews' that I am trying to render. The Proptype for these reviews is as follows: export interface Props { title: string; name: string; reviewdesc: string; rating: number; } In the pare ...