What is causing my function to not wait for the resolution of the Promise?

checkout.ts

updateGlobalValue(){
   updateShadowDomButton(); 
   let globalValue = fetchGlobalValue()
}

web_component_render.ts

let globalValue; 

async fetchData() {
   let booleanFromApi = await callToExternalAPI(); 
   return booleanFromApi; 
}

function updateShadowDOMButton() {
    fetchData.then((booleanFromApi) => {
        globalValue = booleanFromApi;
    })
}

export function fetchGlobalValue() {
    return globalValue;
}

I need to ensure that I retrieve the boolean after the asynchronous call is finished. My assumption was that .then would guarantee that the block of code in then will be executed after the promise resolves. However, while waiting for the execution of the callToExternalAPI, it progresses and retrieves the globalValue. The new global value is then updated once the async call is complete. How can we make sure that the asyncFunction call finishes before retrieving the globalValue?

Answer №1

Let's break down and analyze the flow of your code:

renderButton(){
   renderShadowDomButton(); 
   let globalValue = getGlobalValue()
}

When renderShadowDomButton() is called, it initiates an API call in asyncFunction. Meanwhile, JS proceeds to execute

let globalValue = getGlobalValue()
. As a result, globalValue remains undefined since the API call is still ongoing.


To ensure sequential execution, consider the following approach:

web_component_render.ts

let globalValue; 

async asyncFunction() {
   return await someExternalAPICall(); 
}

async function renderShadowDOMButton() {
    globalValue = await asyncFunction();
}

export function getGlobalValue() {
    return globalValue;
}

checkout.ts

async renderButton(){
   await renderShadowDomButton(); 
   const globalValue = getGlobalValue()
}

Furthermore, here's a more streamlined refactor:

checkout.ts

async renderButton(){
   const globalValue = await getGlobalValue(); 
}

web_component_render.ts

export function getGlobalValue() {
    return await someExternalAPICall();
}

Opt for proper scoping to avoid using global variables within the same file. Also, remember to account for JavaScript's asynchronous nature.

Answer №2

When using the renderShadowDOMButton function, keep in mind that it is asynchronous, meaning the code following it will continue to run without waiting for it to complete.

If you need the value to be retrieved only after the asynchronous function finishes, you can use the following approach:

async renderButton(){
   await renderShadowDomButton(); 
   const globalValue = getGlobalValue()
}

This method should help resolve any issues and ensure the execution halts until the async operation is finalized.

Answer №3

Transitioning from utilizing async/await to .then() does not automatically transform the asynchronous behavior of the code into a synchronous one. The invocation of .then() remains non-blocking, allowing you to merely establish a callback function. Despite setting up the callback, you still need to await its completion before proceeding to the subsequent statement.

I could propose some alternative approaches here and there, but they would simply involve employing promises in a "smart" manner. It is best to stick with asynchronous programming throughout, as both NodeJS and modern browsers fully support async programming, inclusive of top-level await.

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

Unable to retrieve the value of ng-model using $scope

Having some trouble getting the ng-model value when clicking a button that triggers a function to add each ng-model value to an object. Interestingly, when trying to get the value of $scope.shipNameFirst, it shows up as undefined in the second example. I& ...

Exploring the Relationship Between jQuery and JSON through Iterating Over JSON Arrays

There is an array stored in a database: a:4:{i:1;s:4:"1993";i:2;s:4:"1994";i:3;s:4:"1995";i:4;s:4:"1996";} To manipulate this array, I first unserialize it using PHP and then encode it with JSON. The code snippet is as follows: $unwp = unserialize(&apos ...

Is there a way to showcase a PDF file using pdftron through npm?

pdftron/webviewer has been successfully installed "dependencies": { "@pdftron/webviewer": "^7.3.0", "body-parser": "^1.19.0", "express": "^4.17.1", ...

Update WooCommerce Mini-cart with ajax refresh

I'm having an issue with my custom plugin where everything is working properly, except for the fact that the mini cart is not updating after adding items. I have tried various methods to trigger a refresh, but so far nothing has worked. Below is a sni ...

Encountered an error when attempting to submit with Node.js and Express.js connected to MySql - "Cannot POST /login

I am currently working on creating a basic login page using node.js with the express.js and mysql packages. The goal is to redirect users to the layout.html page if their username and password exist in the mysql database. For this project, I have set up a ...

In Javascript, you can compare an array with a nested array and then store the values in a new array

Two arrays are at hand const arrayOne = [ {id: '110'}, {id: '202'}, {id: '259'} ]; const arrayTwo = [ {data: [{value: 'Alpha', id: '001'}]}, {data: [{value: 'Bravo', id: '202'}]}, ...

Assigning a CSS class during the $routeChangeStart event does not activate the animation, unless it is placed within a setTimeout function

Just dipping my toes into Angular, so feel free to correct me if I'm way off base here. I've been working on animating the clamps on both sides of my website to slide in upon the initial page load. You can check out the live version at: Current ...

Can you guide me on how to establish a cookie within a selenium webdriver javascript script?

I am trying to figure out how to set a cookie using a basic webdriver script: WDS.sampleResult.sampleStart(); //WDS.driver.manage().addCookie(new Cookie("connect.sid", "s%3AeexeZcd_-S23Uh30e3Dmd4X9PskWF08s6m5hDurDa5Jj66SupmmiqvKEjAg6HGigl0o0V%2B9R7m4", ...

What do you think of the unique JSON syntax found in the React-Redux-Firebase documentation? Valid or not?

The React-Redux-Firebase documentation showcases a sample code snippet. import { compose } from 'redux' import { connect } from 'react-redux' import { firebaseConnect, populate } from 'react-redux-firebase' const populates = ...

Using Express.js to transform req.body into a POST encoded string

I need to convert the req.body object into a POST encoded string using the express.bodyParser middleware. Is there a way to achieve this? For example: Name: Jane Doe Age: 30 City: Los Angeles Should become: Name=Jane+Doe&Age=30&City=Los+Angeles ...

When the React application loads, loadingbar.js will be mounted initially. However, as the props or states are updated, the object

I recently made the switch from using progressbar.js to loadingBar.js in my React application for widget progress. Everything was working smoothly with progressbar.js, but once I switched to loadingBar.js, I encountered a strange issue. After the page load ...

Sending messages through a Discord Bot without the use of a command

I have code that is constantly running in the background in JavaScript, 24/7. I am looking to configure a discord.js bot to send a notification message if any issues or errors occur within the code. Is there a way to send a message to any channel without ...

What is the best way to incorporate various styles into one :style attribute?

Within my vuetify project, I encountered a challenge of adding multiple styles to the same style attribute. Specifically, I have successfully implemented a vuetify breakpoint and now wish to include {backgroundColor:'Color'} within the existing a ...

Leveraging the power of map in an Angular typescript file

I've been attempting to populate a Map in Angular by setting values dynamically. When certain buttons are clicked, the onClick function is invoked. typeArray: Map<number,string>; Rent(movieId: number){ this.typeArray.set(movieId,"Rental ...

The REST request is preventing the JavaScript on the page from executing

Utilizing REST to POST data through Firefox's Poster tool and encountering a url: http://[ip]/page.jsp?paramater1=whatever&parameter2=whatever (Content Type: application/x-www-form-urlencoded) The page.jsp includes: <body onload="onload()"&g ...

Tips for obtaining a variable step size in react-chartjs-2

I am currently utilizing Chart.js in typescript to create graphical charts. My objective is to dynamically adjust weight values while maintaining a specified minimum and maximum. Specifically, I aim to display 5 ticks on the Y-axis regardless of the incomi ...

The function grunt.task.run() is malfunctioning

Currently, I am experimenting with integrating Grunt into my Express application. Here is a snippet of the code I have: var grunt = require('grunt'); require(process.cwd() + '/gruntfile.js')(grunt); grunt.task.run('development&ap ...

What is the best way to pass a bind value in an Angular function controller?

I am new to working with AngularJS and I'm trying to pass a model bind value into a function declared in the controller. However, when I try to access that value from the controller, it returns undefined. Here is the code snippet: HTML: <div> ...

Using Javascript to create bold text within a string

I have noticed that many people are asking about this issue, but it seems like a clear and simple answer is hard to come by. Currently, I am working with Vue and trying to display text from an object in a component. My goal is to highlight the price port ...

Working with ng-model on an array with multiple dimensions

Currently, I am working on storing data in AngularJS. My table consists of various sections, rows, and columns. In each field, there is a dropdown list with the options "O", "T" or "E". My goal is to store these values in an array format: [section][row][c ...