如何在IE7中控制Javascript线程和重绘

时间:2010-10-22 14:50:45

标签: javascript concurrency

我已经定义了在Web文档准备就绪时执行的函数中有一系列Javascript函数调用。我期望它们按顺序执行,因为一个结束下一个开始,但我看到的行为与之不符。

此外,在调用之间还有对图形组件的操作(例如,我在每个提到的调用之间添加一个检查点时间来绘制页面上的div)但是这些重绘不会发生在顺序......它们都是一次性发生的。

我对浏览器中的整个javascript有点n00b,我正在制作一个明显的错误,还是一个很好的资源去了解如何做这些东西?


更新 - 样本

// called onReady()
function init() {
    doFirstThing();
    updateDisplayForFirstThing();
    doSecondThingWithAjaxCall();
    updateDisplayForSecondThing();
    ...
    reportAllLoaded();
}

3 个答案:

答案 0 :(得分:1)

在当前脚本运行完毕之前,IE不会更新显示。如果要在一系列事件中重绘,则必须使用超时来破坏脚本。

如果您发布一些代码,我们可以帮助重构它。

编辑:这是一个普遍的模式。

function init() { 
    doFirstThing(); 
    updateDisplayForFirstThing(); 
} 

function updateDisplayForFirstThing() {
    // existing code
    ... 

    // prepare next sequence
    var nextFn = function() {
        // does this method run async? if so you'll have to 
        // call updateDisplayForSecondThing as a callback method for the 
        // ajax call rather than calling it inline here.
        doSecondThingWithAjaxCall(); 

        updateDisplayForSecondThing();     
    }

    setTimeout(nextFn, 0);
}

function updateDisplayForSecondThing() {
    // existing code
    ... 

    // prepare next sequence
    var nextFn = function() {
         // continue the pattern 
         // or if you're done call the last method
         reportAllLoaded(); 
    }
    setTimeout(nextFn, 0);
}

答案 1 :(得分:1)

对于许多情况,可以使用回调修复此问题,尤其是使用AJAX调用时 - 例如:

function doFirstThing(fn){
  // doing stuff
  if(typeof fn == 'function') fn();
}

function updateDisplayForFirstThing(){
  // doing other stuff
}

function init(){
  doFirstThing(updateDisplayForFirstThing);
}

另一种选择是使用返回值:

function doFirstThing(fn){
  // doing stuff
  if(x) return true;
  else return false;
}

function updateDisplayForFirstThing(){
  // doing other stuff
  return true;
}

function init(){
  if(doFirstThing()){ updateDisplayForFirstThing(); }
}

设置超时以逐步执行代码并不是解决此问题的好方法,因为您必须将每个代码执行时可能需要的最长时间设置为超时。

但是,您有时可能需要使用setTimeout来确保在某些操作后DOM已正确更新。

答案 2 :(得分:1)

如果您最终决定要使用某种JavaScript线程,请查看仍在起草的Web Workers API。尽管API已在大多数现代Web浏览器中实现,但浏览器支持仍然受到欢迎。

问题:你究竟是怎么决定“doc准备好了”的? IE中不支持DOMContentLoaded事件我非常肯定...如果您需要等待文档全部加载,可以使用以下内容:

var onReady = function(callback) {
    if (document.addEventListener) {
        document.addEventListener("DOMContentLoaded", callback, false);
        return true;
    } else if (document.attachEvent) {
        var DOMContentLoaded = function() {
            if (document.readyState === "complete") {
                document.detachEvent("onreadystatechange", DOMContentLoaded);
                onReady();
            }
        };
        return true;
    }
};

然后当然你需要为一些标志状态开发一个setTimeout测试,指示页面在完成后加载,然后继续执行其余的代码...那个或任意数量的其他方法... < / p>

或者您可以将脚本包含在身体的底部......

我只是漫无目的,直到你有一些代码向我们展示?