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

Clean up requests and callbacks when switching routes

本文关键字:请求 求和 回调 路由      更新时间:2023-09-26

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

我有一个问题,这是由一些API调用可能需要一段时间引起的。当请求花费的时间太长时,一些用户开始在选项卡中快速循环,一个接一个地快速执行每个路由。这将触发所有的集合获取,最终导致接口混乱,因为一些回调将做一些渲染。

所以我的问题是,我怎么能确保每次加载一个新的路由(即使它是在快速连续完成),所有挂起或启动的请求被停止,所以没有"请求成功"回调被触发?

我建议,重写Backbone。视图移除方法。使用常规的stoppllistening,中止ajax调用,也设置一个像this.removed=true这样的标志。在你的渲染函数中检查移除的标志,如果存在不渲染。如果点击完成得非常快,您可能需要在拨打任何电话之前检查它。

基于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');
    }
}

我重写了主干。路由器路由方法如下:

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。停止仍然是假的。