w3c / geolocation

W3C Geolocation API
https://www.w3.org/TR/geolocation/
81 stars 56 forks source link

Promisify `getCurrentPosition()` #174

Open lukewarlow opened 3 weeks ago

lukewarlow commented 3 weeks ago

The geolocation API requires use of callbacks rather than being promise based like modern APIs. However, there is room to offer a promise alternative. If we make the callbacks optional, in the case where they're undefined we could return a promise. This was previously done for Notification.requestPermission. This feels like it should be a relatively simple change to make to the API that little bit more intuitive for new developers.

It'll probably never be possible to deprecate the old syntax but at least it would improve newer code.

The only slightly unfortunate bit would be that setting the options param might need to be done like await navigator.geolocation.getCurrentPosition(undefined, undefined, {...}), this also wouldn't be the first time a parameter needs to be set to an empty value, the same is common for history.pushState()

It feels like watchPosition should/could be updated too but I can't think what that would look like given it fires multiple times?

lukewarlow commented 3 weeks ago

As it turns out I'm not the first to think of this, see https://github.com/w3c/geolocation/issues/48#issuecomment-2041818726 which came to exactly the same idea as I did.

lukewarlow commented 3 weeks ago

The only slightly unfortunate bit would be that setting the options param might need to be done like await navigator.geolocation.getCurrentPosition(undefined, undefined, {...})

I guess you could work around this by making the IDL have the first paramter be a PositionSuccessCallback or PositionOptions but that probably gets messier from an implementation perspective?

reillyeon commented 3 weeks ago

While I love promises as well, my main concern is that the new behavior would be hard to feature detect for, so it is only practical for sites targeting only evergreen browsers (once they all implement it). In contrast, the promise-returning version is extremely easy to polyfill. Basically, I expect that even if we did spec and implement this it would be years before anyone could reliably use it. Maybe that's still worth it?

lukewarlow commented 3 weeks ago

The first parameter is required at the minute so I guess you can try the new approach and if it throws fallback to the old one.

Wouldn't provide any immediate benefit if you needed to handle both.

But regarding it taking years before it's useful, that's true but that's always going to be the case so if we think it's a good idea to change the API shape the sooner it happens and is implemented the sooner it will be usable?

Though as you say it's not super difficult to do in JS so maybe it's not worth it?

mkruisselbrink commented 3 weeks ago

There is also always the slight concern that changing the return type of a method that previously didn't return a promise to now return a promise also means that any exceptions thrown by the method will immediately change into promise rejections instead (i.e. webidl does not support methods that only return a promise for some of its overloads). Although in this case that's probably not much of a problem either since getCurrentPosition doesn't really ever throw an exception anyway (other than in the case of arguments being passed that don't match its signature)