2015-02-10 63 views
1

我正在使用一个简单的函数,它运行一个缓慢的功能之前,它把一个文本在页面中:“加载”。但是该文本仅在功能完成后才显示。 我也尝试添加一个CSS,但它只在函数完成后才运行。内容更改后运行javascript

我把一个例子放在小提琴上,用睡眠功能代替我的大功能。结果是一样的。

http://jsfiddle.net/9nzg9f6L/5/

这里我使用的HTML页面的代码:

<div id='msg'>BEGIN</div>  
<div style="cursor: pointer; color:red;" id='clickme'>click me!</div> 

这里是javascript代码:

$("#clickme").click(function(){ 
    // this code only run after the sleep ... 
    $('#msg').text("PROCESSING"); 

    console.log("text changed"); 

    sleep(5000); 
    console.log("END function"); 

}); 


function sleep(miliseconds) { 
    var currentTime = new Date().getTime(); 
    while (currentTime + miliseconds >= new Date().getTime()) {} 
} 

我不能修改睡眠(5000)函数。它是专有和混淆函数的占位符。

即使是这样: http://jsfiddle.net/9nzg9f6L/7/

不起作用。

+3

这就是___不是你如何在JavaScript中设置一个计时器!一个'while'循环在适当的时间过去之前什么也不做?真的吗?改用['setTimeout'](https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers.setTimeout)。 – Cerbrus 2015-02-10 14:25:56

+1

probme不是setTimeout。 在我的真实代码中,我不打电话给定时器。 我正在使用插件功能。我有同样的行为。另外我不能修改这个功能。 – ricardo 2015-02-10 14:31:19

+0

哦,我明白了...睡眠函数是一个“重功能”的占位符。 – Cerbrus 2015-02-10 14:35:09

回答

2

这里的问题是,因为JavaScript是单线程语言,浏览器只是没有足够的时间在“慢”功能完全阻止UI之前更改DOM。为了克服这种情况通常您可以通过一些很短的时间延迟缓慢的操作,这样糟糕的代码开始工作前,DOM更新可以完成:

$("#clickme").click(function(){ 

    $('#msg').text("PROCESSING"); 
    $('#msg').addClass("message"); 

    setTimeout(function() { 
     sleep(5000); 
    }, 50); 
}); 

演示:http://jsfiddle.net/9nzg9f6L/6/

但是,如果有可能,当然让慢代码异步,这将是这种情况下最好的方法。阻止用户界面永远不是一个好用户体验。也看看WebWorkers

+0

谢谢,这是正确的答案 – ricardo 2015-02-10 15:13:20

4

看看我更新的jsFiddle解决了你的问题。

http://jsfiddle.net/9nzg9f6L/10/

更新的代码

$("#clickme").click(function(){ 

    //Call slow func using a Self Executing func. 
    (function(){ 
     //Create the deferred object to use 
     var defObj1 = $.Deferred(); 

     //Call you slow func 
     $('#msg').text("PROCESSING"); 
     setTimeout(function(){ 
       sleep(5000) 
       defObj1.resolve(); 
     }, 500); 

     return defObj1; 

    })().done(FunctionTwo); 
}) 

//We call this once the Sleep function is done. 
var FunctionTwo = function(){ 
    $('#msg').text("FUNCTION ONE COMPLETED OK.."); 
}; 

//Make it slow.... 
function sleep(miliseconds) { 
    var currentTime = new Date().getTime(); 
    while (currentTime + miliseconds >= new Date().getTime()) {} 
} 

这里我们使用的Self-Executing anonymous functionjQuery's Deferred ObjectsetTimeout确保慢函数执行不停止整个应用程序。一旦完成,我们可以调用函数2,在这种情况下,它简单地输出慢函数完成。

+0

我无法修改睡眠(5000); 其实我没有使用这个睡眠功能。我正在使用另一个具有相同问题的函数。而且我无法修改它,因为它是专有的并且被混淆。 – ricardo 2015-02-10 14:40:02

+0

@RicardoFerreira:但是在Dayan的建议中,你是不是可以在超时中包装“重”功能呢? – Cerbrus 2015-02-10 14:42:09

+0

@Cerbrus,你是对的。 – ricardo 2015-02-10 15:12:21