0

In the following code:

function getPosition() {
    return new Promise((res, rej) => {
        navigator.geolocation.getCurrentPosition(res, rej);
    });
}

function main() {
    getPosition().then(console.log);
}

main();

I'm able to log the Position object in the browser. But what if instead of logging it I want to return that value so that it can be used outside of the then(). Is that possible?

I tried the following:

function main() {
    return getPosition().then();
}

console.log(main());

But instead of viewing my Position object in the log, I see the following:

Promise {<pending>}
__proto__: Promise
[[PromiseStatus]]: "resolved"
[[PromiseValue]]: Position

This doesn't work either

function main() {
    getPosition().then(function(response){
        return response;
    });
}

console.log(main());

I got undefined in the log.

mkrieger1
  • 19,194
  • 5
  • 54
  • 65
user765368
  • 19,590
  • 27
  • 96
  • 167
  • put `return` behind `navigator...` also change `return response` to `return Promise.resolve(response)` – imans77 Sep 11 '18 at 22:30
  • 1
    Possible duplicate of [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) – fubar Sep 11 '18 at 22:31
  • Promise is for managing `async` code https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise – Olivier Boissé Sep 11 '18 at 22:32
  • @imans77 Just tried it and still got undefined – user765368 Sep 11 '18 at 22:35
  • it's asynchronous, so the promise will be resolved after the execution of the `main` function. Add a return statement in the `main` and write `main().then(console.log)` – Olivier Boissé Sep 11 '18 at 22:38
  • All OP needs to do is to add `async` before `main` function, put `await` before calling `main` function, and chop out 90% of the code in `main`. OP clearly asked > I want to *return* that value so that it can be used *outside of the then*. That's EXACTLY what async/await is. Unbelievable that users are steering OP, not a newbie to Javascript, away from that solution. – Steven Spungin Sep 11 '18 at 23:30
  • " so that it can be used outside of the then()"...where and when exactly do you want to use it? The Promise is asynchronous, so you can only use it after the promise has resolved. Your options are either to execute whatever functionality requires the value from within the then() call, or assign the value to a global variable which is then held for later use (e.g. when some other event occurs). – ADyson Sep 12 '18 at 08:15
  • Or very simply you could return the Promise from main() and move the location of the then...e.g. function main() { return getPosition(); } main().then(function(response) { console.log(response) });`. Don't forget you can define as many then(), done() or fail() functions on a Promise as you like, you're not restricted to one. Or as suggested above, you could use await to make the whole thing synchronous again, but that blocks the main thread and kind of removes the whole point of using Promises and asynchronous operations. – ADyson Sep 12 '18 at 08:17

2 Answers2

2

Promise are for handling async operations (think about ajax calls, or code being executed inside a setTimeout), so you can't have something like this

console.log(getPosition().then())

you need to pass a callback to the then method, this callback will be executed when the promised is resolved (think about success callback in jquery)

So basically in your example, you would have something like this :

function main() {
  return getPosition();
}

main().then(console.log);

you can also store the promise in a variable to use it somewhere else in your code

var position = main();

position.then(console.log);
position.then(console.log);
position.then(positionValue => {/* do what you want with the value */});

Note that calling then multiple times will not execute the promise multiple times, it will be resolved only once

Here is the promise documentation

Olivier Boissé
  • 15,834
  • 6
  • 38
  • 56
  • then store the `promise` instead of the final value `var promise = main()`, each time you need the value you call `promise.then(() => ....)` – Olivier Boissé Sep 11 '18 at 22:54
  • Thanks, so wait a minute, I have to use console.log? – user765368 Sep 11 '18 at 23:00
  • `console.log` is just an example, it's a shorcut for `positionValue => console.log(positionValue)`, you can define your own callback – Olivier Boissé Sep 11 '18 at 23:03
  • You need to put all the other code that want to use the value inside the `then()`. `console.log` isn't the only thing you can put in a callback – slebetman Sep 11 '18 at 23:03
0

You can use async/await

async function main() {
    console.log(await getPosition());
}

Here is a working snippet that demonstrates this:

function getPosition() {
    return new Promise((res, rej) => {
        // simulate API
        setTimeout( ()=> res('123,456'), 1000)
    });
}

async function main(){
  console.log(await getPosition())
}

main()
Steven Spungin
  • 27,002
  • 5
  • 88
  • 78
  • it's not a good idea to mix everything up, I think the OP should first understand how Promise work before using `async await` (which behind the scene use es6 generator) – Olivier Boissé Sep 11 '18 at 23:07
  • @OlivierBoissé I disagree. In the end, they are the same. async/await is easier to read/write/debug. I have heard this argument before. OP needs to understand the concept of async callback functions, regardless of the syntax being `then` or async/await. In addition, having functions marked async makes it very clear that they are async. – Steven Spungin Sep 11 '18 at 23:11