gpt4 book ai didi

javascript - jQuery .each 在附加 html 之前等待所有操作完成

转载 作者:行者123 更新时间:2023-12-02 19:07:36 24 4
gpt4 key购买 nike

我正在研究一种方法,可以将 php 程序的多个实例更新为同一版本,而无需付出太多努力。

我的软件会检查 RSS 源,其中包含有关最新版本的信息。如果发现有可用更新,则会显示指向“更新”页面的链接。当用户单击“更新”链接时,我有一个 jquery 函数可以一次更新每个需要更新的文件:

$.getJSON('http://softwareserver.com/updateFileList.php?fromver=1.0', function(data) {
var filesToDo = data.length;

$.each(data, function(num, file) {
num = num + 1;
action = file.charAt(0);
name = file.substring(1);

if ( action == "+" )
{
$('#upsole').append("<p><strong>Adding</strong> " + name + ". . .</p>");
$.get("{$var['sbpurl']}/updateAction.php", { action: "add", file: name, revision: "{$TMP['rev']}" } );
}

else if ( action == "-" )
{
$('#upsole').append("<p><strong>Removing</strong> " + name + ". . .</p>");
$.get("{$var['sbpurl']}/updateAction.php", { action: "remove", file: name, revision: "{$TMP['rev']}" } );
}

else if ( action == "~" )
{
$('#upsole').append("<p><strong>Updating</strong> " + name + ". . .</p>");
$.get("{$var['sbpurl']}/updateAction.php", { action: "update", file: name, revision: "{$TMP['rev']}", version: "{$TMP['ver']}" } );
}

var completed = num / filesToDo * 100;

$('#barcolor').css('width', completed + '%');
$('#numProgress').html(completed.toFixed(0));

if ( completed == 100 )
{
$('#conutt').html('<a href="index.php" class="button"> Continue > </a>');
$('#upsole').append("<p><strong>Update Complete</strong></p>");
}
});
});

我在 div 容器中显示正在更新的每个文件名;我还有一个进度条,随着每个文件的更新,进度条从 0-100% 变化,直到所有文件都已更新。但当全部完成时,进度条只是从 0 变化到 100。它实际上并没有像我希望的那样显示每个文件之间更新的进度。

我希望我的进度条从 0% 到 7%、15% 等,直到达到 100%,但在全部完成之前什么也不会发生..所以正如我所说,它只是从 0% 到100%。

$.each 不是最好的解决方案吗?

最佳答案

不,$.each 不太适合这项工作。您的主要问题是浏览器中的 JavaScript 是单线程的,因此您的所有 DOM 都会更新:

  • $('#upsole').append(...)
  • $('#barcolor').css(...)
  • $('#numProgress').html(...)

只会在浏览器重新获得控制权时排队等待处理。那么浏览器什么时候才能重新获得控制权呢?当然是在 $.each 完成之后。您会看到结果:用户看到事情从无到有一步完成。您还需要考虑 $.get 的异步性质。

每次 DOM 更新后,您都需要将控制权交还给浏览器。您有一堆 $.get 调用,因此您可以使用它们的成功回调将 DOM 更改与浏览器对这些更改的响应交错。像这样的事情:

$.getJSON('http://softwareserver.com/updateFileList.php?fromver=1.0', function(data) {
var filesToDo = data.length;
var next_one = function() {
var file = data.shift();
if(!file) {
// If `data` is empty then we're all done so we can put the UI into
// the "update complete" state and end the process by not calling
// next_one() again.
$('#conutt').html('<a href="index.php" class="button"> Continue &gt; </a>');
$('#upsole').append("<p><strong>Update Complete</strong></p>");
return;
}

// Set up the next iteration by parsing `file`. We put the `$.get` stuff
// into an object so that we only have one `$.get` call; the reason for
// this will be clear shortly.
var action = file.charAt(0);
var name = file.substring(1);
var get = { };
if(action == '+') {
get = {
msg: '<p><strong>Adding</strong> ' + name + '...</p>',
url: "{$var['sbpurl']}/updateAction.php",
params: { action: "add", file: name, revision: "{$TMP['rev']}" }
};
}
else if(action == '-') {
//...
}
else if(action == '~') {
//...
}

// Tell them what we're about to do...
$('#upsole').append(get.msg);

// This `$.get` call is asynchronous so the browser will get control here
// and any pending DOM updates will be applied.
$.get(get.url, get.params, function() {
// Update the DOM with the latest status.
var completed = (filesToDo - data.length) / filesToDo * 100;
$('#barcolor').css('width', completed + '%');
$('#numProgress').html(completed.toFixed(0));

// And trigger the next iteration.
next_one();
});
};

// Crank it up.
next_one();
});

基本思想是迭代data直到它为空,每次迭代都会删除data的第一个元素,这样我们就可以检测data<的结尾 (以及我们迭代的结束)通过查看它何时返回 undefined (这是错误的)。每次迭代都会触发一个 $.get,它将控制权返回给浏览器以允许更新 DOM。 $.get 回调将触发下一次迭代。

诸如错误处理之类的细节留给读者作为练习。

关于javascript - jQuery .each 在附加 html 之前等待所有操作完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14176841/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com