animation problem when value changes while setTimeout timer’s running

function wallpaperMediaPropertiesListener(event) {

    // reset animation
    test.stop(true);
    test.css('margin-left', 0);
    
    // set song title.
    test.text(event.title);
    var testWidth = test.outerWidth();
    
    // clone text
    $('.test-copy').remove();
    if (testWidth > $('#line1').width()) {
        test.clone().css({'margin-left': gap, 'font-size': '1.05vh'}).removeClass().addClass('test-copy').insertAfter(test);
    }
    
    // move text
    let speed = 5;
    function shiftingAnimation() {
        let timer = setTimeout(() => {
            test.animate({'margin-left': -(testWidth + gap)}, {
            duration: Math.abs((testWidth + gap) * 100 / speed),
            easing: 'linear',
            complete: function () {
                test.css({'margin-left': 0});
                clearTimeout(timer);
                shiftingAnimation();
            }
            });
        }, 3000);
    }

    // first execution
    if (testWidth > $('#line1').width()) {
        setTimeout(shiftingAnimation, 3000);
    }

}

event.title returns song name that is playing.
wallpaperMediaPropertiesListener function will be triggered when song changes.

animation starts after 3s delay when testWidth > #line1 width. when animation ends, it repeats itself with 3s delay each time. if event.title value changes, it resets animation and start from first 3s delay and so on.

but when event.title value changes while setTimeout timer in if statement is running, it ignores if statement or first 3s delay and applies animation to it even if condition is false (not certain what is actually happening but at least it looks like it).