不良的算法触发并发循环 [英] javascript - bad algorithm firing concurrent loops

查看:68
本文介绍了不良的算法触发并发循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个相对较小的动态横幅旋转脚本,在底部带有图标,以使特定横幅成为焦点。在横幅上触发Mouseent会暂停显示,但是有时当我从横幅上将鼠标移出时,某些横幅的延迟会缩短。我什至知道它是否只发生过一次,但是每次横幅轮换回来时,延迟都设置为较短的时间,通常缩短发生在横幅列表中的另一个位置,例如好。有时,这可以通过尚未确定的一组动作来纠正。我开始怀疑我的逻辑在中间某个地方捕获了循环,因此该过程分支出来,运行了两个循环,这似乎加快了showNextBanner函数的调用。不知道如何解决这个问题。我已经进行了测试,以查看它当前是否处于播放模式,但无济于事。

I created a relatively small dynamic banner rotation script with icons at the bottom for bringing a particular banner into focus. Firing a mouseenter over a banner pauses the show, but sometimes when I mouseout from my banner, the delay for certain banners gets shortened. I'd even understand if it just happened once, but the delay is then set for that shorter amount of time every time the banner comes back around in the rotation, and often the shortening happens in one other place in the list of banners, as well. Sometimes this can be corrected by an as yet undetermined set of actions. I'm starting to suspect that my logic is catching the loop in the middle somewhere and so the process branches out, runs two loops, which appear to speed up the calling of the showNextBanner function. Not sure how to solve this. I've put in tests to see if it's currently in play mode, to no avail.

我包括以下代码的相关部分。

I include what I think are the relevant parts of the code below.

        var firstRun = true;
        var play = true;
        var current = 0;

        var banners = $$( '.banner' ); 
        banners.invoke( 'hide' );
        var images = $$( '.image' );
        var icons = $$( '.icon' );
        //dynamically clones an initial icon to match the number of banners
        initIcons();

        banners.invoke( 'observe', 'mouseenter', function( field ) {
            play = false;
        });

        banners.invoke( 'observe', 'mouseleave', function( field ) {
            if( !play ) {
                play = true;
                showNextBanner().delay(3);
            }
        });

        icons.invoke( 'observe', 'click', function( field ) {
                play = false;
                hideBanner( current );
                showBanner( findObj( icons, field.findElement()));
        });


        showNextBanner().delay(3); 


        function hideBanner( which ) {
            icons[ which ].src = blankIconSRC;
            banners[ which ].hide();
        }


        function showBanner( which ) {
            icons[ which ].src = selectedIconSRC;
            banners[ which ].show();
            current = which;
        }


        // loops the hiding and showing of icons 
        // (mouseenter sets play to false)
        function showNextBanner() {
            if( play ) {
                if( !firstRun ) {
                    if( ++current == banners.length ) current = 0;    
                    var previous = 0;
                    ( current == 0 )? previous = banners.length - 1: previous = current - 1;
                    hideBanner( previous );
                } else {
                    icons[0].src = selectedIconSRC;
                    firstRun = false;
                }
                showBanner( current );
                showNextBanner.delay(3);
            }
        }
    }());






毕竟,客户端需要jQuery解决方案因此他可以具有无法通过脚本实现的滑入效果。因此,所有的工作都花在了费力上。好消息是,我大概可以使用jCarousel并调整样式表。感谢您的帮助!


After all that, the client wants a jQuery solution so he can have a slide-in effect not available via scriptaculous. So all that work is down the drain. The good news is that I can just use jCarousel, probably, and tweak the stylesheet. Thanks for the help!

推荐答案

我怀疑正在发生的事情是您堆积了多个.delay调用。因此,剩下的时间不到3秒,再次调用showNextBanner,设置另一个延迟计时器。

I suspect what is happening is that you've got multiple .delay calls stacking up. So you've got one with less than 3 seconds remaining and showNextBanner is called again, setting another delay timer.

在我阅读文档时,似乎是.delay在jQuery事件管道中留出空隙,而不是实际延迟函数调用。您可能会受益于切换到调用setTimeout而不是延迟,因此您可以获得超时的句柄,然后可以在设置新超时之前取消该超时(或在play设置为false时取消,然后在play再次为true时重置)在 .delay的jQuery文档中提到了这一点

As I read the docs, it appears .delay is intended to put gaps in the jquery event pipeline, rather than actually delay function calls. You may benefit from switching to calling setTimeout instead of delay, so that you get a handle to the timeout, which you can then cancel before setting a new timeout (or cancel if play is set to false, then reset when play is true again) This is mentioned in the JQuery docs for .delay

这篇关于不良的算法触发并发循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆