0

I have a async function which returns a promise. I'm confused to how I access the Promise value. I came across .then(). It works with .then(), but I want to make the promise value global. Which isn't possible if i use .then().

Here is my code:

async function getUser() {  
  try {    
    response = await axios.post('/',data);  
  } 
  catch (error) {   
    console.error(error);  
  }  
  return response.data;
}

var global = getUser(); 
console.log(global);

This code here returns a promise like so:

screenshot function return value

I'm wondering how can I access the Promise value (which we can see in the image) and make it global? I'm new to JavaScript unable to wrap my head around async functions.

3limin4t0r
  • 19,353
  • 2
  • 31
  • 52
Sai Darshan
  • 252
  • 3
  • 13
  • [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – Andreas Apr 21 '20 at 10:22
  • `var global = await getUser();` – Moritz Roessler Apr 21 '20 at 10:22
  • await can be used only inside a async function right ?Moritz Roessler – Sai Darshan Apr 21 '20 at 10:24
  • if u notice var global is outside the async function – Sai Darshan Apr 21 '20 at 10:25
  • @EaGLE Right! Just wrap your call in an async iife. `(async () => {var global = await getUser();})()` – Moritz Roessler Apr 21 '20 at 10:25
  • Using `async`/`await` means you can write code in a synchronous way again, without callbacks and the like. The "downside" is that once you enter into the async code, you can never leave it again. Which means that if you store the result of an async call in a global variable, you can only reliably access it in the same async context. Outside you'll get only the Promise. To put it simpler: `console.log(global)` is called *before* the axios call finishes, not after. –  Apr 21 '20 at 10:28
  • But then again variable "global" will not have a global scope – Sai Darshan Apr 21 '20 at 10:29
  • Yes @Chris G.So at the end of the day.it is not possible to make a async function value global? – Sai Darshan Apr 21 '20 at 10:30
  • It is absolutely possible. You can set a global variable to the result of some `await` call for instance. Then you need to make sure the variable is only accessed *after* the call has finished. Example: https://jsfiddle.net/khrismuc/eLcbpvfh/ It all depends on how you're going to use the variable, or rather: *when*. –  Apr 21 '20 at 10:35
  • I saw your example.Can you please explain how that would translate to my code? – Sai Darshan Apr 21 '20 at 10:55
  • 1
    You are storing the promise in a global variable perfectly fine already. All you need to do is to consume its value using `global.then(data => console.log(data))` instead of `console.log(global)` – Bergi Apr 21 '20 at 10:57
  • I want to make "data" accessable in a global scope.Is it possible? – Sai Darshan Apr 21 '20 at 10:59
  • Maybe if you shared why you want it global, we can explain an alternative solution to your objective. Using the result of a promise globally is not possible in a clean way. – Ben Butterworth Apr 21 '20 at 11:10
  • @EaGLE Possible, yes, but pointless, because noone who wants to use the data would know when/whether it already has loaded. – Bergi Apr 21 '20 at 13:45

2 Answers2

1

You can't. Using async means your function actually wraps a promise around it. So global in var global = getUser() is a promise. You can either await in in an async function or use .then().

If you want the code to look synchronous, you could have a main function, and just call main 'globally':

async function main() {
   // because main is an async function, it can unwrap the promise
   const user = await getUser();
   console.log({user});
}

main();

You should not try to use user 'globally', and only use it in main. This is because the promise of getUser might not even be done yet, so it would be unresolved promise. You should only use it when you explicitly waited (await or then'd) the promise. Also, global variables are not great in any programming language, including javascript.

Ben Butterworth
  • 22,056
  • 10
  • 114
  • 167
  • I understand your answer perfectly.But my doubt is that how can i make 'user' global.So that i can access it outside the main() function? – Sai Darshan Apr 21 '20 at 11:03
  • By `main` here, I mean its wraps your entire application/ code. Nothing should be called globally, except `main()`. Just stick everything in `main()`. If you have other files, import/ require them in this file, and use them in `main` or functions that are called in `main` – Ben Butterworth Apr 21 '20 at 11:06
0

You can set your global value like so:

var global;
getUser().then(user => global = user);

function getUser() {
  return Promise.resolve("User #1");
}

var global;
getUser().then(user => global = user);

console.log("1", global);
setTimeout(() => console.log("2", global), 500);

However keep in mind that other synchronous code has no idea when the global variable is set. The value will be undefined until the callback is called. The better option might be what you're already doing:

var global = getUser();

This way other synchronous code can attach callbacks by doing:

global.then(user => {
  // ...
});

function getUser() {
  return Promise.resolve("User #1");
}

var global = getUser();

global.then(user => console.log("1", user));
setTimeout(() => {
  global.then(user => console.log("2", user));
}, 500);
3limin4t0r
  • 19,353
  • 2
  • 31
  • 52