是否可以在Promise中包装Geolocation.watchPosition()等函数?

时间:2017-03-02 08:11:20

标签: javascript geolocation async-await ecmascript-2017

我想知道是否可以将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)
    }
  }
}

1 个答案:

答案 0 :(得分:0)

还没有。

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

在ES2015中我们得到了发电机:function*& yield,允许 Iterators - 使用yield ... for循环拉动每个of

Generators还支持使用var valToGet = yield foo;generator.next(valToPush);语法推送 Observers

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

在ES2017中,我们获得了async& await - 这些使用生成器来将await中的每个async function转换为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 ... 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);
    }
}

所以异步迭代器/ observable即将到来,但要先排序很多。

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