簡體   English   中英

外部拒絕在Ember中承諾的承諾

[英]Externaly Rejecting Pending Promises In Ember

摘要:

我們的Ember應用程序遇到以下情況,並且正在努力尋找合適的解決方案。

我們正在處理大量數據,因此我們對數據的一些要求相當慢。

最初我們使用Em.RSVP.hash在每個路由的模型鈎子中“捆綁”我們的請求。 然而,這會鎖定用戶界面並最終無法接受。

我們的解決方案是在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並且可能重新考慮慢查詢的需要。

謝謝。

首先,在“工作”解決方案中,您不會在signOut期間取消慢查詢。 您只是拒絕終止承諾鏈的承諾,以便不再發送請求。 (當signOut返回之前的最后一個查詢時,它仍然可以改變您的cookie。)

如果這對您來說已經可以接受,那么您需要做的是將對signOut感知的檢查插入到promise鏈中,以便在用戶退出時立即終止它。

didSignOut: false

setupController: (controller, model) ->
    slowRequest1WhichReturnsAPromise().then ->
        return null if didSignOut
        slowRequest2WhichReturnsAPromise().then ->
            return null if didSignOut
            slowRequest3WhichReturnsAPromise().then ->
                return null if didSignOut
                // ...

動作:signOut: - > @set('didSignOut',true)

return null可以替換為您想要執行的任何操作。 如果你想要一個集中的方式來處理這個事件,你仍然可以通過第二個參數拒絕承諾RSVP.on("error", ...) .then()並為它設置一個RSVP.on("error", ...)處理程序。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM