3

我想知道是否可以将Geolocation.watchPosition() https://developer.mozilla.org/en-US/docs/Web/API/Geolocation/watchPosition包装在 Promise 中,并以一种可行的方式将其与async/await成语一起使用;每当设备的位置发生变化并调用后续函数时,都会不断返回位置。

// 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)
    }
  }
}
4

1 回答 1

0

还没有。

您描述的模式是一个Observable - Javascript 中没有对它的语言支持,但它即将到来。

在 ES2015 中,我们得到了生成器:function*& yield,它允许迭代器yield-用for...of循环拉动每个迭代器。

生成器还支持 push Observers, withvar valToGet = yield foo;generator.next(valToPush);语法。

生成器是同步的——它们只是来回传递一个线程。

在 ES2017 中,我们得到了async& await- 这些在幕后使用生成器将每个awaitin转换async function为 a yield new Promise(...async function成为promises迭代器。

理想情况下,我们可以做这样的事情:

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...语法,只是笨拙的,所以使用这个假设的方法有点难看:ofgenerator.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);
    }
}

所以异步迭代器/可观察对象即将到来,但首先要解决很多问题。

同时,有一些支持观察者模式的特殊库现在可用,例如RxJS

于 2017-03-06T17:28:19.773 回答