检查JS中是否重新输入异步功能

问题描述 投票:1回答:1

场景:

我们有一个MutationObserver处理函数handler

handler中,我们进行了一些DOM操作,这些操作将再次触发handler。从概念上讲,我们将有一个可重入的handler调用。除了MutationObserver未在线程中运行外,它会在handler已完成执行后触发。

因此,handler将触发自己,但会通过异步队列而不是线程内触发。 JS调试器似乎知道这一点,它将在调用栈(即使用Chrome)中作为异步祖先出现。

为了实现事件的有效反跳,我们需要对其进行检测;也就是说,如果handler是由于自身触发的更改而被调用的。

该怎么办?

mutationObserver=new MutationObserver(handler);
mutationObserver.observe(window.document,{
    attributes:true,
    characterData:true,
    childList:true,
    subtree:true
});

//  Trigger a MutationObserver change
document.getElementById('foo').setAttribute('class','bar');
document.getElementById('foo').setAttribute('class','');

var isHandling;
function handler(){
    console.log('handler');

    //  The test below won't work, as the re-entrant call 
    //  is placed out-of-sync, after isHandling has been reset
    if(isHandling){
        console.log('Re-entry!');
        //  Throttle/debounce and completely different handling logic
        return;
    }
    
    isHandling=true;
    
    //  Trigger a MutationObserver change
    document.getElementById('foo').setAttribute('class','bar');
    document.getElementById('foo').setAttribute('class','');
    
    isHandling=false;
}
<div id="foo"></div>
javascript mutation-observers
1个回答
0
投票

一种可能的解决方法是在触发一个突变时停止突变观察者

mutationObserver=new MutationObserver(handler);
mutationObserver.observe(window.document,{
    attributes:true,
    characterData:true,
    childList:true,
    subtree:true
});

//  Trigger a MutationObserver change
document.getElementById('foo').setAttribute('class','bar');
document.getElementById('foo').setAttribute('class','');

function handler(){
    console.log('Modification happend')

        mutationObserver.disconnect();
    //  Trigger a MutationObserver change
    document.getElementById('foo').setAttribute('class','bar');
    document.getElementById('foo').setAttribute('class','');

    mutationObserver.observe(window.document,{
    attributes:true,
    characterData:true,
    childList:true,
    subtree:true
});
}

请参见JS小提琴

https://jsfiddle.net/tarunlalwani/8kf6t2oh/2/

© www.soinside.com 2019 - 2024. All rights reserved.