简体   繁体   English

Ajax complete在成功之前就被解雇了,如何防止这种行为呢?

[英]Ajax complete is fired before success is ready, how can one prevent this behaviour?

I have an AJAX request which fetches a chunk of HTML which I insert into the DOM. 我有一个AJAX请求,该请求获取插入到DOM中的HTML块。 While this is happening I am showing a spinner loading gif. 发生这种情况时,我正在显示微调器加载gif。

I want the spinner to hide at the exact same time as the data received from the ajax request is inserted into the DOM. 我希望微调器在从ajax请求接收的数据插入DOM的确切时间隐藏。

The problem is that the javascript starts executing the complete part before the HTML is actually inserted into the DOM. 问题在于,在HTML实际插入DOM 之前 ,javascript开始执行完整的部分。 So for the end user the spinner goes away and a while after, the DOM pops up. 因此,对于最终用户,微调框消失了,过了一会儿,DOM弹出了。

 $('#mySpinner').show();
 $.ajax({
     success: function(data) {
         $('#myElement').html(data);
     },
     complete:(){
         $('#mySpinner').hide(); // This is called when the success part is still executing
     }
 });

EDIT: I'm not saying complete is fired before success. 编辑:我并不是说完成是成功之前被解雇的。 I am saying complete is fired before success is ready . 我的意思是说,在成功准备就绪之前,必须先完成工作。 So the order in what happens is this: 因此,发生的顺序是:

  1. Success is called 成功被称为
  2. $('#myElement').html(data); is called 叫做
  3. Complete is called 完成称为
  4. $('#mySpinner').hide() is called $('#mySpinner').hide()被称为
  5. $('#mySpinner').hide() is finished $('#mySpinner').hide()完成
  6. $('#myElement').html(data); is finished 完成了

Just do this then : 然后执行以下操作:

$('#mySpinner').show();
$.ajax({
    success: function(data) {
     $('#myElement').html(data);
     $('#mySpinner').hide();
 }

});

But the behaviour you describe is not inline with jQuery doc as complete should only occur after success and error ... can you reproduce this wrong behaviour in a jsFiddle ? 但是您描述的行为并不与jQuery Doc内联,因为complete的行为仅应在successerror之后发生……您可以在jsFiddle中重现此错误行为吗? It might be the problem is somewhere else... 可能是问题出在其他地方...

html() runs synchronously, however the browser could still be rendering when the next statement is executed. html()同步运行,但是当执行下一条语句时,浏览器仍然可以呈现。 You could try to add a simple setTimeout to give the browser time to display the added content: 您可以尝试添加一个简单的setTimeout,以使浏览器有时间显示添加的内容:

$('#mySpinner').show();
$.ajax({
    success: function(data) {
        $('#myElement').html(data);
        setTimeout(function() {
            $('#mySpinner').hide();
        }, 0);
    },
    error: function() {
        $('#mySpinner').hide();
    } 
});

Another option is to add a specific element to the added html and only continue when that element exists: 另一个选择是将特定元素添加到添加的html中,并且仅在该元素存在时才继续:

function waitForDom(el, cb) {
    if ($(el).length) {
        $(el).remove();
        cb();
        return;
    }

    setTimeout(function() {
        waitForDom(el, cb);
    }, 10);
}

$('#mySpinner').show();
$.ajax({
    success: function(data) {
        $('#myElement').html(data + '<div id="waitForDom"></div>');

        waitForDom("waitForDom", function() {
            $('#mySpinner').hide();
        });
    },
    error: function() {
        $('#mySpinner').hide();
    } 
});

You can simply hide your spinner in success part of ajax code: 您可以简单地将微调器隐藏在ajax代码的成功部分中:

$('#mySpinner').show();
 $.ajax({
     success: function(data) {
         $('#myElement').html(data);
         $('#mySpinner').hide();
     }
 });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM