2016-10-25 13 views
1

私はをRxJSのPromisesチェーンから作成しようとしています。 this questionとの違いは私には未知数の約束があり、すべての約束は前の結果に依存するということです。PromiseのシーケンスをRxJSでRx.Observableに変換する方法は?

基本的には、私は一連のページを持っており、「次のページ」のリンクに接続されています。

私は機能がやりたいことはある:約束<>

  • ため

    • 待ち結果(火observer.onNextを())を提供
    • チェック次のページリンク
    • があれば
    • ページがあるまで、そのリンクで>
    • 繰り返しを次の約束<の作成は
    のまま

    私は次のことを試してみました:

    private getPages<T>(firstPromise: PromiseLike<IODataCollectionResult<T>>): Rx.Observable<T> { 
    
        let observable = Rx.Observable.create<T>(async obs => { 
         let page = await firstPromise; 
         page.value.forEach(v => obs.onNext(v)); 
    
         while (page['@odata.nextLink']) { 
          let nextPageUrl = <string>page['@odata.nextLink']; 
          let nextPagePromise = <PromiseLike<IODataCollectionResult<T>>>this.resource(nextPageUrl).get().$promise; 
          page = await nextPagePromise; 
          page.value.forEach(v => obs.onNext(v)); 
         } 
    
         obs.onCompleted(); 
        }); 
    
        return observable; 
    } 
    

    IODataCollectionResultは、次のページのURLと.VALUEは、値の配列です '@ odata.nextLink' ODataの結果、である)

    問題私は活字体で、それは私にエラーを与えることをコンパイルすることはできませんです:

    非同期関数はPromise<void>を返すので、意味がない可能

    Argument of type '(obs: Observer) => Promise' is not assignable to parameter of type '(observer: Observer) => void | Function | IDisposable'.

    a void

    Rx.Observable.create()でasync/awaitを使用できないということですか?どのようにして一連の約束をオブザーバブルにすることができますか?

  • 答えて

    0

    問題は(.then使用して解決した)+再帰:

    private getPages<T>(initialPromise: PromiseLike<IODataCollectionResult<T>>): Rx.Observable<T> { 
        return Rx.Observable.create<T>(obs => { 
         const getPage = (promise: PromiseLike<IODataCollectionResult<T>>) => { 
          promise.then(page => { 
           page.value.forEach(v => obs.onNext(v)); 
           if (page['@odata.nextLink']) { 
            let nextPageUrl = <string>page['@odata.nextLink']; 
            let nextPagePromise = <PromiseLike<IODataCollectionResult<T>>>this.resource(nextPageUrl).get().$promise; 
            getPage(nextPagePromise); 
           } 
           else { 
            obs.onCompleted(); 
           } 
          }); 
         } 
         getPage(initialPromise); 
        }); 
    } 
    
    適切なエラーハンドラをアタッチする代わりにそれを使用し、約束を捨てないでください。
    1

    あなたはその結果を無効に何かにasync functionをラップすることができます。それに

    function toVoid<A>(fn: A => Any): A => Void { 
        return x => void fn(x) 
    } 
    

    (活字体の私の欠けている知識を許すが、私はあなたがそれを行うことになっているものを推測することができることを望む)

    を、あなたは

    let observable = Rx.Observable.create<T>(toVoid(async obs => { 
        … 
    })); 
    

    を呼び出すことができるはずしかし、多分あなたはそれを行うべきではありません。非同期/のawaitせず、

    let observable = Rx.Observable.create<T>(obs => { 
        (async() => { 
         … 
        }()).catch(err => { 
         obs.onError(err); 
        }); 
    }); 
    
    関連する問題