2017-03-02 7 views
3

プロンプトでGeolocation.watchPosition()https://developer.mozilla.org/en-US/docs/Web/API/Geolocation/watchPositionをラップして、それが仕事のやり方でasync/awaitのイディオムで使用できるかどうかは疑問です。デバイスの場所が変更されたときに常に位置を返し、後続の関数を呼び出します。Geolocation.watchPosition()などの関数をPromiseでラップすることはできますか?

// 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) 
    } 
    } 
} 
+0

[このオブザーバブル提案](https://github.com/tc39/proposal-observable/blob/master/README.md)のようなものですか? – gyre

+0

これは*できますが、約束は一度起こる必要があることに理想的です。 Observableのようなリスナーモデルはもっとはっきりしています。 – lonesomeday

答えて

0

まだありません。

あなたが記述しているパターンが観察可能ある - そこの言語サポートは、JavaScriptではありませんが、それは来ています。 - for ... ofループで各yieldを引っ張っfunction* & yieldイテレータを許可:

はES2015では、発電機を得ました。

ジェネレータもまた、のオブザーバvar valToGet = yield foo;generator.next(valToPush);シンタックスをサポートしています。

ジェネレータは同期型です。単一のスレッドを前後に通過しているだけです。 ES2017では

我々はasync & awaitを得た - カバーの下でこれらの使用・ジェネレータはyield new Promise(...async functionの各awaitを変換します。 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も、両方ではないことができます。また、そこだけ不格好generator.next(pushValue)イテレータのためのものですので、この仮想的な方法は少し醜いですがかかるように素敵なfor ... of構文ではありません。

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など)。

関連する問題