4

概要:

Ember アプリで次のような状況に遭遇し、適切な解決策を見つけるのに苦労しています。

大量のデータを扱っているため、一部のデータ リクエストはかなり遅くなります。

最初に、Em.RSVP.hash を使用して、各ルートのモデル フックにリクエストを「バンドル」しました。ただし、これは UI をロックするため、最終的には受け入れられませんでした。

私たちの解決策は、次のように setupController フックでリクエストをカスケードすることでした。

setupController: (controller, model)->
    slowRequest1WhichReturnsAPromise().then (data)->
        # Do something with request 1 data

        slowRequest2WhichReturnsAPromise().then (data)->
            # Do something with request 2 data

            slowRequest3WhichReturnsAPromise().then (data)->
                # Do something with request 3 data

これは機能します。ページの読み込みが瞬時に行われ、最も関連性の高いデータが最初に表示されます。

Ember を最新の状態に保つように努めています (執筆時点では 1.11.3)。Ember Data は使用していません。

問題:

問題は、UI のロックが解除されていることです。たとえば、ユーザーはログアウトできます (そして、ログイン ページにリダイレクトされます)。リクエストは持続し、最終的には完了し、ログインとログアウトで設定した csrf トークンを台無しにします。次にユーザーがログインしようとすると、422 エラーが発生します。

さらに単純なシナリオは、実行時間の長い要求が終了する前にフィルター設定を変更することです。新しいリクエスト (多くの場合、フィルタの変更によってスコープが縮小されます) は、最初のリクエストの前に終了します。その後、データは、最終的に終了する元の要求によって上書きされます。

私たちの当面の解決策は、保留中の約束を殺そうとすることでしたが、それを行う「最新の」方法を見つけることができませんでした。

これは機能します:

allPromises: []

setupController: (controller, model)->
    deferredRequest1 = new Em.RSVP.defer()

    # Store all promises
    @get('allPromises').pushObject(deferredRequest1)

    # Fire off request 1
    # Spark up the next stage when request 1 finishes
    deferredRequest1.promise.then ->
        deferredRequest2 = new Em.RSVP.defer()
        @get('allPromises').pushObject(deferredRequest2)

# ... 
actions:
    signOut: ->
        @get('allPromises').forEach (promise)->
            promise.reject('canceled')

上記は、ポイントを理解するために少し見苦しく単純化されています。

Ember Docs には、「新しいコードは (遅延の) 代わりに RSVP.Promise コンストラクターを使用する必要がある」と記載されています。ただし、新しい方法を使用してこれを行う方法はないようです。

質問:

保留中の約束/要求をキャンセルする最新の方法はありますか?
保留中のリクエストをクリーンな方法でキャンセルできるように、ページの読み込みを分割するより良い方法はありますか?

アップデート

私は延期を使用することになった。美しくはありませんが、UI をリファクタリングし、おそらく遅いクエリの必要性を再考するまでは十分でしょう。

ありがとうございました。

4

1 に答える 1