我循环遍历数组,在循环的每次迭代中,我通过ajax调用url。我还想更新一个.innerHTML,使其显示以使用户知道正在处理循环的哪个迭代。但是,.innerHTML仅在脚本完成时显示更新。
如何在循环中显示此通知?
我也在使用查询ajax设置'async:false'。我不想一次处理所有ajax请求,因为他们正在编码CPU密集型的视频文件。我真的不想锁定浏览器等待同步请求完成。
有更好的方法吗?
我的最终目标是为每组视频顺序执行我的combine.php脚本,同时向用户显示当前状态指示器,同时不在此过程中锁定浏览器。感谢您的帮助!
此处的代码段:
// process the loop of videos to be combined
var status = document.getElementById('currentStatus');
for (i=0; i< count; i++) {
// change the display
var fields = videos[i].split(":", 2);
current = i +1;
currentStatus.innerHTML = "<b>Multi-part Videos:</b> <h3 class='status'>Currently Updating Bout #" + fields[1] + " (" + current + " of " + count + " videos)</h3>";
// run the combine
var dataString = 'videoId='+ fields[0];
$.ajax({
type: "POST",
url: "combine.php",
data: dataString,
success: function(txt) {
//deselect the checkbox
document.combine.video[selected[i]].checked = false;
},
async: false
});
// process the loop of videos to be combined
var status = document.getElementById('currentStatus');
for (i=0; i< count; i++) {
// change the display
var fields = videos[i].split(":", 2);
current = i +1;
currentStatus.innerHTML = "<b>Multi-part Videos:</b> <h3 class='status'>Currently Updating Bout #" + fields[1] + " (" + current + " of " + count + " videos)</h3>";
// run the combine
var dataString = 'videoId='+ fields[0];
$.ajax({
type: "POST",
url: "combine.php",
data: dataString,
success: function(txt) {
//deselect the checkbox
document.combine.video[selected[i]].checked = false;
},
async: false
});
答案 0 :(得分:1)
async: false
将挂起整个浏览器,直到ajax请求完成。这就是为什么你没有看到每次循环迭代的页面更新。
同步ajax请求通常会导致可怕的用户体验(你像页面一样莫名其妙地冻结?)并且几乎总有一种更好的方法可以做到这一点。由于你正在使用jQuery,Deferred Object API使这很容易。
答案 1 :(得分:1)
正如其他人所提到的,你的问题是因为JavaScript是单线程的 - 而单个JS线程正在等待你的ajax请求返回,所以不允许更新UI。
您可以通过将请求更改为异步来解决此问题,并使用回调来触发对下一个对象的请求:
// trigger the loop of videos to be combined
var status = document.getElementById('currentStatus');
processVideo( 0 );
function processVideo( index ) {
var fields = videos[index].split(":", 2);
currentStatus.innerHTML = "<b>Multi-part Videos:</b> <h3 class='status'>Currently Updating Bout #" + fields[1] + " (" + current + " of " + count + " videos)</h3>";
// run the combine
var dataString = 'videoId='+ fields[0];
$.ajax({
type: "POST",
url: "combine.php",
data: dataString,
success: function() {
processResponse( index);
},
async: true
});
}
function processResponse( index ) {
// this method is called each time the ajax request finishes
if (index++ < count) {
//deselect the checkbox
document.combine.video[selected[index]].checked = false;
processVideo( index );
}
}
答案 2 :(得分:0)
如果要在async设置为true时逐个更新,则可以将下一个请求放入成功回调函数中。更新状态代码也应该在该函数内部。
function ajaxRequest(i){
// other processing
.............
$.ajax({
type: "POST",
url: "combine.php",
data: dataString,
success: function(txt) {
//deselect the checkbox
document.combine.video[selected[i]].checked = false;
// update status
currentStatus.innerHTML = .....
// make next request
if(i<lastOne){
ajaxRequest(i+1);
}
},
async: true
});
}