setTimeout和clearTimeout中断

时间:2016-09-21 15:54:35

标签: javascript css angularjs

我正在尝试像丢弃警报队列一样。 到目前为止,我已经实现了它。当我尝试实施中断时,问题出现了。 假设一个离线事件触发一个警报,在它结束之前超时,在线事件触发。我希望它能够杀死离线警报,并显示在线警报。 事情是,在这种情况下,超时不会像我期望的那样工作。

以下是处理警报的Angular服务:

.factory('AlertDrop', ['$rootScope', '$q', function ($rootScope, $q) {
        var timeout = 2000;
        $rootScope.DropAlerts = [];
        var hideonclick = false;
        var listenerOn = false;
        var t = this;
        this.currentAlert = {};

        var getColor = function (clase) {
            switch (clase) {
                case 'error':
                    return 'rgba(201,48,44,0.9)';
                    break;
                case 'warning':
                    return 'rgba(240,173,78,0.9)'
                    break;
                case 'success':
                    return 'rgba(68,157,68,0.9)'
                    break;
                case 'info':
                    return 'rgba(49, 176, 213,0.9)'
                    break;
                default:
                    console.log('Código de color incorrecto. Cargo color por defecto.');
                    return 'rgba(152,26,77,0.9)';
                    break;
            }
        };

        this.requestTypes = [
            {
                type: 'offline',
                class: 'error'
            },
            {
                type: 'online',
                class: 'success'
            }
        ];

        this.bgcolor = 'rgba(201,48,44,0.9)';

        this.showAlert = function (params) {
            this.currentAlert = params;
            delete t.ctout;
            t.ctout = {};
            var deferred = $q.defer();


            if (params.timeout) {
                this.timeout = params.timeout
            }

            if (params.hideonclick) {
                hideonclick = params.hideonclick;
            }

            if (params.class != '')
                this.bgcolor = getColor(params.class);

            if (params.class != '') {
                $('.alertDrop').attr('style', 'background: ' + this.bgcolor + '; top:44px;');
            } else {
                $('.alertDrop').attr('style', 'top:44px;');
            }

            if (hideonclick) {
                addListener(this.bgcolor);
            }

            $('.alertDrop').html(params.message);

            t.ctout = setTimeout(function () {
                timeoutDone();
            }, this.timeout);
        };

        this.hideAlert = function (color) {
            $('.alertDrop').css('top', '0');
            rmListener();
        };

        var rmListener = function () {
            if (listenerOn) {
                $('.alertDrop').unbind('click');
            }
        };

        var addListener = function (color) {
            if (!listenerOn) {
                //    $('.alertDrop').on('click', t.hideAlert(color));
            }
        };

        var timeoutDone = function(){
            var deferred = $q.defer();
            t.hideAlert(this.bgcolor);
            var tt = setTimeout(function(){
                t.changeStatus(false);
                deferred.resolve(true);
            },2000); // 2 segundos, tiempo establecido en style.css
            return deferred.promise;
        };

        var removeOnlines = function(){
            $rootScope.DropAlerts = $rootScope.DropAlerts.filter(function(el){
                return el.type != 'online';
            });
        };

        var removeOfflines = function(){
            $rootScope.DropAlerts = $rootScope.DropAlerts.filter(function(el){
                return el.type != 'offline'
            });
        };

        var interrupcion = function(params){
            var load = true;
            if(params.type == 'offline'){
                removeOnlines(params);
                load = false;
            }else if(params.type == 'online'){
                removeOfflines(params);
                load = false;
            }
            if(load){
                $rootScope.DropAlerts.push(params);
            }else{
                clearTimeout(t.ctout);
                timeoutDone().then(function(){
                    t.showAlert(params);
                });
            }
        };

        this.checkPush = function(params){
            var deferred = $q.defer();
            if( $rootScope.AlertDropActive ){
                if( params.type == this.currentAlert.type ){
                    clearTimeout(this.ctout);
                    setTimeout(function(){
                        timeoutDone();
                    },this.timeout)
                }else{
                    interrupcion(params);
                }
                deferred.resolve(true);
            }else{
                $rootScope.DropAlerts.push(params);
                deferred.resolve(true);
            }
            return deferred.promise;
        };

        this.pushAlert = function (params) {
            this.checkPush(params);
            if (!$rootScope.AlertDropActive) {
                this.changeStatus(true);
                var alert = $rootScope.DropAlerts.shift();
                this.showAlert(alert);
            }
        };

        this.changeStatus = function(v){
            $rootScope.AlertDropActive = v;

            if (!$rootScope.AlertDropActive && ( $rootScope.DropAlerts.length > 0 )) {
                this.changeStatus(true);
                var alert = $rootScope.DropAlerts.shift();
                this.showAlert(alert);
            }
        };

        return {
            showAlert: this.showAlert,
            hideAlert: this.hideAlert,
            pushAlert: this.pushAlert,
            changeStatus: this.changeStatus,
            currentAlert: this.currentAlert,
            checkPush: this.checkPush
        };
    }]);

因此,当我触发中断功能时,只有在连接重新建立或丢失的情况下,我需要停止当前超时,并且一旦隐藏警报,就会显示新事件。

我在div上显示这个,转换为2秒。

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

实际上错误不在我发布的代码上,而是在我调用pushAlert时。 我添加了一个超时,以便尝试模拟快速事件更改,这就是乱七八糟的事情。