主干:中止以前的路由器回调执行
Backbone: abort previous router callback execution
假设我的页面上有 2 个链接:
<a href="#A">Link A</a>
<a href="#B">Link B</a>
我使用骨干路由器来处理应用内页面导航。
在路由链路"#A"上,我已经为"#B"注册了一个侦听器 A 和类似的侦听器 B,其中侦听器 A 和侦听器 B 都在后台执行一些繁重的任务。
现在,假设用户单击"链接 A",并在几毫秒的间隔内单击"链接 B"。
因此,发生的情况是,当侦听器 A 完成其执行时,只有当侦听器 B 由于单个 UI 线程而开始执行时。
有没有办法,如果请求侦听器 B,我可以阻止/中止/抢占侦听器 A 的执行?
预计用户希望看到其最新操作的响应。如果两个操作相似,则不应遵循以前的操作。
要了解 Backbone 如何处理路由,让我们查看Backbone.History
中的一些代码块:
if (this._hasPushState) {
Backbone.$(window).on('popstate', this.checkUrl);
} else if (this._wantsHashChange && ('onhashchange' in window) && !oldIE) {
Backbone.$(window).on('hashchange', this.checkUrl);
} else if (this._wantsHashChange) {
this._checkUrlInterval = setInterval(this.checkUrl, this.interval);
}
如果您使用的是现代浏览器,则第二个如果黑色将订阅hashChange
事件,并且任何时候您从一个链接导航到另一个链接时,它将调用checkUrl
这将管理对适当操作的调用。
所以对你的问题直接回答是否定的,你不能。
但是,您可以使用一些解决方法,具体取决于您在操作中执行的操作。
第一个解决方案。
使用setTimeout()
或类似的_.debounce()
功能。选择所有需要保护或单独处理的链接,然后导航到所需的URL:
$(document.body).on('click', 'a:not([reference-to-out])', function(e){
e.preventDefault();
if (app.linkTimeoutId) {
clearTimout(app.linkTimeoutId);
}
app.linkTimeoutId = setTimeout(function () {
app.linkTimeoutId = null;
app.router.navigate(e.currentTarget.pathname, {trigger: true});
}, 500)
});
第二个解决方案
如果您的繁重任务与网络相关(获取收集,对远程执行另一个请求),请跟踪它们保留在另一个对象中,并在 Backbone.Router 触发"路由"事件时取消它们。这将防止许多不必要的操作。
第三种解决方案
我在考虑$.Deferred
对象,但在这种情况下,您应该用它包装控制器的所有操作并跟踪它们。
您可以更改 Backbone 处理路由注册的方式,以便在路由匹配和执行其回调之间引入延迟。例如
var Router = Backbone.Router.extend({
routes: {
":id" : "go"
},
route: function(route, name, callback) {
var router = this;
if (!callback) callback = this[name];
var f = function() {
var args = _.toArray(arguments);
console.log('Clicked route', args[0]);
if (router.timer)
clearTimeout(router.timer);
router.timer = setTimeout(function() {
callback.apply(router, args);
}, 1000);
};
return Backbone.Router.prototype.route.call(router, route, name, f);
},
go: function(id) {
console.log("Routed "+id);
}
});
var r = new Router();
Backbone.history.start();
导航到路线将设置计时器。如果在给定的时间间隔内发生另一次导航,则会取消计时器并中止操作。
请参阅 http://jsfiddle.net/nikoshr/0ws8d0ky/以获取演示
- AngularJS:我可以跳过函数参数回调吗
- 要求未定义JS回调参数
- MeteorJS:在带有回调的vzaar api上正确使用wrapAsync
- 自引用回调
- 测试Angular Service解决错误回调中的promise
- 如何将一个JavaScript函数回调为多个函数
- JavaScript回调函数
- 用于回调的javascript参数
- 将json回调数据转换为日期
- 未为路由器应用程序调用Node.Js的回调
- 主干.js路由器回调,用于在除 1 个特定 URL 段之外的所有 URL 段上触发
- 主干:中止以前的路由器回调执行
- 突出显示具有骨干路由器回调的所选项目
- Reactjs路由器匹配回调参数总是未定义的
- AngularJS -在重新加载/更改路由器时触发回调
- 延迟回调中的异常:错误:路由器上没有配置uiManager
- 同一路由器上的多个.use()会导致覆盖回调
- 从回调传递变量到express路由器
- 在angular ui路由器状态解析中从$http获取错误回调
- 快速路由器回调