2017-03-02 4 views
3

Geolocation.watchPosition()https://developer.mozilla.org/en-US/docs/Web/API/Geolocation/watchPosition을 약속에 넣고 async/await 관용구로 사용하는 것이 가능한지 궁금합니다. 장치의 위치가 변경되고 후속 기능을 호출 할 때마다 위치를 계속 반환합니다.Promise에서 Geolocation.watchPosition()과 같은 함수를 래핑 할 수 있습니까?

// 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

[이 Observables 제안]과 같은 것 (https://github.com/tc39/proposal-observable/blob/master/README.md)? – gyre

+0

이 작업은 * 할 수 있지만 약속은 한 번 발생해야하는 작업에 이상적입니다. Observable과 같은 리스너 모델은 훨씬 더 분명합니다. – lonesomeday

답변

0

아직 없습니다.

설명하는 패턴은 입니다. 관찰 가능 - 자바 스크립트에는 언어 지원이 없지만 곧 출시 될 예정입니다. - for ... of 루프 각 yield를 당겨 function* & yield, 반복자 허용 :

는 ES2015에서 우리는 발전기를 얻었다.

발전기는 옵저버var valToGet = yield foo;generator.next(valToPush); 구문을 지원합니다.

발전기는 동기식입니다. 단일 스레드를 앞뒤로 전달합니다.

는 ES2017에서 우리는 async & await있어 - 내부적으로이 사용 발전기는 yield new Promise(... 내로 async functionawait을 변환 할 수 있습니다. 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 ...이, 반복자에 대한 바로 어설픈 generator.next(pushValue), 그래서이 가상 방법을 소모하는 것은 조금 못생긴처럼 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).