-1

checkout.ts

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

web_component_render.ts

let globalValue; 

async asyncFunction() {
   let booleanFromAsync = await someExternalAPICall(); 
   return booleanFromAsync; 
}

function renderShadowDOMButton() {
    asyncFunction.then((booleanFromAsync) => {
        globalValue = booleanFromAsync;
    })
}

export function getGlobalValue() {
    return globalValue;
}

I want to fetch the boolean after the async call is completed. My understanding was .then should ensure that the block of code in then will be executed after the promise resolved. However, while waiting for execution of the someExternalAPICall, it moves forward and gets the globalValue. The new global value is then updated after the async call completes. How can I ensure the code completes asyncFunction call and then gets the globalValue?

shailesh
  • 1
  • 2
  • 2
    Generally, don't use globals, and especially not with async functions. Please share a [mcve] and provide context for what you're trying to achieve here. You'll need promises all the way to where you use an async value: `let globalValue = await getGlobalValue()` and `async`/`await` all along that chain, at the very least. Easier is to just export the function that has the promise and call it directly. – ggorlen Oct 07 '22 at 15:47
  • Most of your assumptions are correct, however, the .then doesn't stop `getGlobalValue` from returning whatever is currently in `globalValue`. It'd be best to just always return a promise in cases like this. – Kevin B Oct 07 '22 at 15:48
  • On stackoverflow, people can help so much more meaningfully if you show REAL code. This is a make-up example with no real asynchronous code showing. There could be lots of things wrong with the real code such as a function not returning a promise that is connected to when the asynchronous operation completes. That happens all the time here. So, not sure how we can help when we can't see a minimal, reproducible example of real code. – jfriend00 Oct 07 '22 at 16:18

3 Answers3

0

Let's dissect and see what happens in your code here:

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

renderShadowDomButton will call some random API in asyncFunction. While the API call is being made, JS then runs let globalValue = getGlobalValue(). At this point, the API call is not done yet. Hence, globalValue will be undefined.


If you want it to run one after the other, try the following:

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()
}

However, I'll go one step further and help you refactor:

checkout.ts

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

web_component_render.ts

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

As much as possible, we do not want any global var even within the same file. Keep them scoped well. Also, take note of the asynchronous of JS.

Kiong
  • 798
  • 1
  • 8
  • 28
0

renderShadowDOMButton is an asynchronous function that means the code you put after it will continue executing without waiting for it to finish.

in order to force getting the value to wait until the asynchronous function is done you can do this.

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

this should solve your problem and stop the execution until the async call is done.

Mustafa
  • 323
  • 2
  • 11
-1

Moving from async/await to .then() doesn't magically change the asynchronous nature of the code to synchronous. The call to .then() is non-blocking, meaning you only set up a callback. You want to set the callback up and then wait for it to complete before moving to the next statement. That's not going to happen.

I could give you some variant here and there, but they will just be some "clever" use of promises. Stick with asynchronous programming all the way and all will be fine. NodeJS and the browsers now fully support async programming, including top-level await's.

José Ramírez
  • 872
  • 5
  • 7