【发布时间】:2015-05-13 22:42:19
【问题描述】:
总结:
我们的 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 并重新考虑对慢查询的需求之前,它会起作用。
谢谢。
【问题讨论】:
-
是的,有一些支持正确取消的现代承诺库。但是,
RSVP似乎不是其中之一。
标签: javascript ember.js promise rsvp-promise