切换路由时清理请求和回调

时间:2014-07-21 14:13:51

标签: javascript backbone.js backbone-events backbone-routing

我有一个骨干应用程序,可以将API中的一些数据加载到图表中。此应用程序有几个选项卡,可以导航以访问这些不同的图表,每个选项卡执行一个路径。每个图表都是ChartView的一个实例,其中包含相应的数据。

我遇到一些可能需要一段时间的API调用问题。当请求花费太长时间时,一些用户开始快速循环通过选项卡,彼此之后快速执行每个路由。这会激活所有集合提取,最终会破坏界面,因为一些回调会进行一些渲染。

所以我的问题是,我怎样才能确保每次加载新路由时(即使是快速连续完成)所有待处理或已启动的请求都已停止,因此没有"请求成功&#34 ;回调被解雇了?

2 个答案:

答案 0 :(得分:1)

我建议,覆盖Backbone.Views删除方法。使用常规stopListening,中止ajax调用,还设置类似this.removed=true的标志。在渲染功能中检查已移除的标志,如果存在则不进行渲染。如果点击已经很快完成,您可能需要在拨打任何电话之前进行检查。

答案 1 :(得分:1)

根据Ravi Hamsa的回复,我实施了一个对象,该对象被注入到每个路径中以保存请求以及路由是否仍然相关。

看起来像这样:

var RouteContext = function RouteContext() {
    this._xhrs = {};
    this.stopped = false;

    this.manageRequest = function(xhr) {
        this.xhrs.push(xhr);
    }

    this.stop = function() {
        this.stopped = true;
        _.invoke(this.xhrs, 'abort');
    }
}

我重写了Backbone.Router路由方法,如下所示:

route: function(route, name, callbackFactory) {
    var callback;

    if (_.isFunction(callbackFactory)) {
        var context = new RouteContext();
        callback = callbackFactory(context);

        // When a new route is opened, this route should be stopped and all
        // corresponding jqXHR's should be aborted.
        App.mediator.on('tabClicked', function() {
            context.stop();
        });
    } else {
        callback = callbackFactory;
    }

    return Backbone.Router.prototype.route.call(this, route, name, callback);
}

我现在可以使用这样的上下文创建一个新的路由方法:

var routeFactory = function(routeContext) {
    // Might do some route initialisation here.

    return function() {
        this.reset(routeContext);
        // This function is the actual function that will be called when a route is triggered.

        if (routeContext.stopped === false) {
            myView.renderChart();
        }
    }
};

// Register the route on the router.
myRouter.route('route', 'name', routeFactory); 

因为可以多次调用路由,所以当重新调用路由时,我将RouteContext重置为原始状态。

在我的路线中,我一直在检查我需要做什么,以便渲染routeContext.stopped是否仍为false。如果确实如此,我不进行渲染。