使用 setTimeout 函数时出现问题

发布于 2024-12-08 16:40:44 字数 1755 浏览 0 评论 0原文

我一直无法正确使用 setTimeout 函数,因此我尝试编写示例脚本来更新进度条,但同样,它不起作用。相反,整个程序会在进度条更新到 100% 之前运行。有人可以查看这段代码并告诉我我做错了什么吗?

我尝试使用的代码来自 http://digitalbush.com/projects/progress-酒吧插件/

谢谢!

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<script language="javascript" type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
<script src="http://digitalbush.com/wp-content/uploads/2007/02/jqueryprogressbar.js" type="text/javascript"></script>
<title>Progress Bar test</title>
</head>
<body>
<style>
    /* progress bar container */
    #progressbar{
        border:1px solid black;
        width:200px;
        height:20px;
        position:relative;
        color:black; 
    }
    /* color bar */
    #progressbar div.progress{
        position:absolute;
        width:0;
        height:100%;
        overflow:hidden;
        background-color:#369;
    }
    /* text on bar */
    #progressbar div.progress .text{
        position:absolute;
        text-align:center;
        color:white;
    }
    /* text off bar */
    #progressbar div.text{
        position:absolute;
        width:100%;
        height:100%;
        text-align:center;
    }
</style>

<div id="progressbar"></div>
<input type='button' value='start' onClick='run()' />

<script>
function run() {
    for (i=0; i<100; i++) {
        setTimeout( function() {
            $("#progressbar").reportprogress(i);
        }, 500);
    }
}
</script>
</body>
</html>

I've never been able to properly use the setTimeout function, so I tried writing a sample script to update a progress bar, but again, it does not work. Instead, the entire program runs before the progress bar is updated to 100%. Would somebody be able to look at this code and tell me what I'm doing wrong?

The code I'm trying to use is from http://digitalbush.com/projects/progress-bar-plugin/

Thanks!

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<script language="javascript" type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
<script src="http://digitalbush.com/wp-content/uploads/2007/02/jqueryprogressbar.js" type="text/javascript"></script>
<title>Progress Bar test</title>
</head>
<body>
<style>
    /* progress bar container */
    #progressbar{
        border:1px solid black;
        width:200px;
        height:20px;
        position:relative;
        color:black; 
    }
    /* color bar */
    #progressbar div.progress{
        position:absolute;
        width:0;
        height:100%;
        overflow:hidden;
        background-color:#369;
    }
    /* text on bar */
    #progressbar div.progress .text{
        position:absolute;
        text-align:center;
        color:white;
    }
    /* text off bar */
    #progressbar div.text{
        position:absolute;
        width:100%;
        height:100%;
        text-align:center;
    }
</style>

<div id="progressbar"></div>
<input type='button' value='start' onClick='run()' />

<script>
function run() {
    for (i=0; i<100; i++) {
        setTimeout( function() {
            $("#progressbar").reportprogress(i);
        }, 500);
    }
}
</script>
</body>
</html>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

﹏半生如梦愿梦如真 2024-12-15 16:40:44

setTimeout 不是 sleep(JavaScript 没有 sleep)。

当您循环时,您将函数设置为在 500 毫秒内运行,然后立即将其设置为在 500 毫秒内再次运行,依此类推。因此,您可以有效地将其设置为在 500 毫秒内运行 100 次,并在第一次执行之前将 i 设置为 100(因为 JS 引擎运行 for 循环 100 所需的时间不到半秒)次)。

你想要更多这样的东西:

var interval, i = 0;
interval = setInterval(function () {
    if (i === 100) {
        clearInterval(interval);
    } else {
        $("#progressbar").reportprogress(i);
        i++;
    }
}, 500);

setTimeout is not sleep (JavaScript doesn't have a sleep).

As you loop round, you set the function to run in 500ms, then you immediately set it to run again in 500ms, and so on. So effectively, you set it to run 100 times in 500ms, and have set i to 100 before the first time it executes (since it takes a JS engine less then half a second to run that for loop 100 times).

You want something more like this:

var interval, i = 0;
interval = setInterval(function () {
    if (i === 100) {
        clearInterval(interval);
    } else {
        $("#progressbar").reportprogress(i);
        i++;
    }
}, 500);
毁我热情 2024-12-15 16:40:44

问题是变量i成为闭包的一部分,并且当函数执行时,它已经等于100

您当前的代码实际上创建了一百个引用同一变量(全局 i)的超时。当所有函数执行完毕时,i 等于 100,因此您将 100 报告为当前进度 100 次。

正确的版本应该是这样的:

function run() {
    var i = 0;
    setTimeout( function updateProgress() {
        $("#progressbar").reportprogress(i++);
        if (i < 100){
            setTimeout(updateProgress, 500);
        }
    }, 500);
}

您可以检查 javascript 花园的 closures 部分以获得解释和可能的其他解决方案。

The issue is that variable i becomes the part of the closure and, when the function is executed, is already equal to 100.

The code you have currently literally creates a hundred of timeouts referencing the same variable(global i). By the time all of the functions are executed, i equals 100, therefore you report 100 as current progress 100 times.

The proper version should look like that:

function run() {
    var i = 0;
    setTimeout( function updateProgress() {
        $("#progressbar").reportprogress(i++);
        if (i < 100){
            setTimeout(updateProgress, 500);
        }
    }, 500);
}

You could check closures part of javascript garden for explanation and possible other solutions.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文