是否可以在 Promise 中包装诸如 Geolocation.watchPosition() 之类的函数?
Is it possible to wrap function such as Geolocation.watchPosition() in a Promise?
我想知道是否可以将 Geolocation.watchPosition()
https://developer.mozilla.org/en-US/docs/Web/API/Geolocation/watchPosition 包装在一个 Promise 中,并以某种方式将其与 async/await
习语一起使用;每当设备的位置发生变化并调用后续功能时,就会不断 returns 定位。
// Example Class
class Geo {
// Wrap in Promise
getCurrentPosition(options) {
return new Promise((resolve, reject) => {
navigator.geolocation.getCurrentPosition(resolve, reject, options)
})
}
// Wrap in Promise
watchCurrentPosition(options) {
return new Promise((resolve, reject) => {
navigator.geolocation.watchPosition(resolve, reject, options)
})
}
// Works well.
async currentPosition() {
try {
let position = await this.getCurrentPosition()
// do something with position.
}
catch (error) {
console.log(error)
}
}
// Any way...?
async watchPosition() {
try {
let position = await this.watchCurrentPosition()
// do something with position whenever location changes.
// Invoking recursively do the job but doesn't feel right.
watchPosition()
}
catch (error) {
console.log(error)
}
}
}
还没有。
您描述的模式是一个 Observable - Javascript 中没有语言支持,但即将推出。
在 ES2015 中我们得到了生成器:function*
& yield
,它允许 迭代器 - 用 [=15= 拉动每个 yield
]...of
循环。
Generators 还支持推送 Observers,使用 var valToGet = yield foo;
和 generator.next(valToPush);
语法。
生成器是同步的 - 它们只是来回传递一个线程。
在 ES2017 中,我们得到了 async
和 await
- 它们在幕后使用生成器将 async function
中的每个 await
转换为 yield new Promise(...
。 async function
成为 承诺 的 迭代器 。
理想情况下,我们可以这样做:
async watchPosition*() {
try {
while(this.enabled) {
// Loop each time navigator.geolocation.watchPosition fires success
const position = await this.watchCurrentPosition();
// Pass back to the listener until generator.next
const atDestination = yield position;
if(atDestination)
break; // We're here, stop watching
}
}
catch (error) {
console.log(error)
}
}
遗憾的是,尚不支持 async function*
- 函数可以是生成器或 async
,但不能同时是两者。也没有很好的 for
...of
语法,就像迭代器那样,只有笨拙的 generator.next(pushValue)
,所以使用这个假设的方法有点难看:
async listener() {
const generator = Geo.watchPosition();
let item = await generator.next(false);
while (!item.done) {
// Update UI
const atDestination = areWeThereYet(item.value);
item = await generator.next(atDestination);
}
}
所以异步 iterators/observables 即将到来,但首先要解决很多问题。
与此同时,有一些支持观察者模式的特殊库现在可用,例如 RxJS。
我想知道是否可以将 Geolocation.watchPosition()
https://developer.mozilla.org/en-US/docs/Web/API/Geolocation/watchPosition 包装在一个 Promise 中,并以某种方式将其与 async/await
习语一起使用;每当设备的位置发生变化并调用后续功能时,就会不断 returns 定位。
// Example Class
class Geo {
// Wrap in Promise
getCurrentPosition(options) {
return new Promise((resolve, reject) => {
navigator.geolocation.getCurrentPosition(resolve, reject, options)
})
}
// Wrap in Promise
watchCurrentPosition(options) {
return new Promise((resolve, reject) => {
navigator.geolocation.watchPosition(resolve, reject, options)
})
}
// Works well.
async currentPosition() {
try {
let position = await this.getCurrentPosition()
// do something with position.
}
catch (error) {
console.log(error)
}
}
// Any way...?
async watchPosition() {
try {
let position = await this.watchCurrentPosition()
// do something with position whenever location changes.
// Invoking recursively do the job but doesn't feel right.
watchPosition()
}
catch (error) {
console.log(error)
}
}
}
还没有。
您描述的模式是一个 Observable - Javascript 中没有语言支持,但即将推出。
在 ES2015 中我们得到了生成器:function*
& yield
,它允许 迭代器 - 用 [=15= 拉动每个 yield
]...of
循环。
Generators 还支持推送 Observers,使用 var valToGet = yield foo;
和 generator.next(valToPush);
语法。
生成器是同步的 - 它们只是来回传递一个线程。
在 ES2017 中,我们得到了 async
和 await
- 它们在幕后使用生成器将 async function
中的每个 await
转换为 yield new Promise(...
。 async function
成为 承诺 的 迭代器 。
理想情况下,我们可以这样做:
async watchPosition*() {
try {
while(this.enabled) {
// Loop each time navigator.geolocation.watchPosition fires success
const position = await this.watchCurrentPosition();
// Pass back to the listener until generator.next
const atDestination = yield position;
if(atDestination)
break; // We're here, stop watching
}
}
catch (error) {
console.log(error)
}
}
遗憾的是,尚不支持 async function*
- 函数可以是生成器或 async
,但不能同时是两者。也没有很好的 for
...of
语法,就像迭代器那样,只有笨拙的 generator.next(pushValue)
,所以使用这个假设的方法有点难看:
async listener() {
const generator = Geo.watchPosition();
let item = await generator.next(false);
while (!item.done) {
// Update UI
const atDestination = areWeThereYet(item.value);
item = await generator.next(atDestination);
}
}
所以异步 iterators/observables 即将到来,但首先要解决很多问题。
与此同时,有一些支持观察者模式的特殊库现在可用,例如 RxJS。