JavaScript 附加子项 (div) 仅在执行完所有代码后显示

JavaScript appended child (div) only shows up after ALL code has been executed

长话短说:获得了一个上传文件元素和一个带有 onclick 功能的按钮,名为 "start"。因此,所有这些都是在所有 DOM 内容加载完成后发生的。

createLoader: function(){
    var outerDiv = document.createElement('div');
    var innerDiv = document.createElement('div');
    innerDiv.className = '_gisplayloader';

    var mapDiv = this.getContainer();

    /*outerDiv.style = ' opacity: 0.5; background-color: grey; justify-content: center; display: flex;';
    outerDiv.style.position = 'absolute';
    outerDiv.style.zIndex = '999999999';*/
    outerDiv.className = '_gisplayLoaderOuterDiv';
    outerDiv.style.height = mapDiv.offsetHeight;
    outerDiv.style.width = mapDiv.offsetWidth;
    outerDiv.appendChild(innerDiv);
    this.loaderDiv = outerDiv;

    mapDiv.parentElement.insertBefore(outerDiv, mapDiv);
}

这是 loader/spinner 创建和附加代码。如果我通过浏览器控制台调用它,它会立即工作。

在 start() 内部,它读取上传的文件,onloadend 调用另一个调用 createLoader() 的函数。

function start(){
    //var data = new Array();
    var time = Date.now();

    console.log("starting...");

    var reader = new FileReader();
    reader.onloadend = function(){
        var data = JSON.parse(reader.result);
        var datareadtimestamp = Date.now();
        makeChoropleth(map, data ,options,null);
    }
    reader.readAsText(document.getElementById("file").files[0]);    
}

makeChoropleth 函数的简化版本:

makeChoropleth: function(bgmap, geometry, options,defaultid){

    var gismap = new Choropleth(bgmap, geometry, options); //inside here it calls createLoader()

    //the next 3 functions take about 5-10s to execute all together
    gismap.processData(geometry);
    gismap.draw();
    gismap.buildLegend();

    if(options.loader != false){
        //  gismap.loader(); that would hide the loader. disabled it so i could check if the loader was appearing at all
    }
}

除非我在 makeChoropleth 中的某处放置断点,否则加载程序只会在所有代码完成时显示。下面的代码几乎需要 10 秒才能完成,这足以创建加载程序(假设它是异步的)。为什么会这样?如何修复它?

如果您希望加载程序在文件完成读取之前出现,您需要在 onloadend 事件之前在 start() 函数中调用它。

function start(){
    //var data = new Array();
    var time = Date.now();

    console.log("starting...");

    var reader = new FileReader();
    reader.onloadend = function(){
        //stuff here only runs after the file is read completely!
        var data = JSON.parse(reader.result);
        var datareadtimestamp = Date.now();
        makeChoropleth(map, data ,options,null);
    }
    reader.readAsText(document.getElementById("file").files[0]);
    createLoader();    
}

如果您希望加载程序在文件读取完成后但在 Choropleth 代码 运行s 之前显示,最简单的方法是在 5-10 秒的操作上设置 1 毫秒的超时时间,以便给浏览器时间做回流焊。 (否则阻塞代码将首先 运行 )。尝试:

makeChoropleth: function(bgmap, geometry, options,defaultid){

    var gismap = new Choropleth(bgmap, geometry, options); //inside here it calls createLoader()

    //the next 3 functions take about 5-10s to execute all together
    setTimeout(function(){
        gismap.processData(geometry);
        gismap.draw();
        gismap.buildLegend();
    },1);

    if(options.loader != false){
        //  gismap.loader(); that would hide the loader. disabled it so i could check if the loader was appearing at all
    }
}