Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

MutationObserver的同异步问题

  MutationObserver是DOM树的监控神器,但目前的实现中还有许多问题(有些问题将在Firefox的下一个版本中被修复,这里不介绍了)。同异步问题就是这些问题的其中之一,在Chrome与Firefox上MutationObserver不知是算同步还是算异步,完全没有逻辑。
  下面的代码将在Chrome37和Firefox32中得到不同的结果: <body>
<script>
var mo=new MutationObserver(function(e){
  e.forEach(function(e){
    Array.prototype.forEach.call(e.addedNodes,function(e){
      if(e.nodeType==1)console.log("事件触发");
    });
  });
});
mo.observe(document.body,{childList:true});
</script><script>
console.log("主消息中的代码");
</script>

  从以上测试结果来看,在Firefox中这个事件触发是异步的,而在Chrome中则是同步的。但实时并非如此,这不仅仅是同步异步那么简单的概念了,下面代码会出现预料之外的结果
<body>
<script>
setTimeout(function(){
  console.log("setTimeout回调");
});
var mo=new MutationObserver(function(e){
  e.forEach(function(e){
    Array.prototype.forEach.call(e.addedNodes,function(e){
      if(e.nodeType!=1)return;
      console.log("事件触发");
      document.write("</strong>test");
      document.close();
    });
  });
});
mo.observe(document.body,{childList:true});
</script><strong>test
<script>
console.log("在STRONG中的SCRIPT");
</script>
  如果Firefox中这个事件真是异步的,那它的结果应该是事件在setTimeout之后才触发,而且document.write会重写整个文档。但实时上不是这样

  而Chrome如果说是同步的话,文档应该不被重写。但事实上不是这样

  不过在Chrome的结果中,setTimeou在事件之后执行,以及另一个SCRIPT标签没被执行,这两点确实有同步的感觉。
  这就是MutationObserver的奇葩之处之一,我也说不清谁对谁错,甚至不知道这时候到底应该用何种方式处理才合适。我觉得在规范MutationObserver等这些东西之前要先把计时器、消息等相关的概念重新做一个规范,要不然真没法解决。
网名:
3.80.55.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^