【问题标题】:updated UI not showing before sync ajax call在同步 ajax 调用之前未显示更新的 UI
【发布时间】:2017-08-01 05:59:10
【问题描述】:

我有 2 个 JavaScript 函数,它们一个接一个地调用。喜欢以下。

updateUI(event);
syncCall();

function updateUI(event) {
  formSubmitBtn = $(event.target).find('[type=submit]:not(".disabled")');
  formSubmitBtn.attr('disabled', 'disabled');
  var loadingText = I18n.t('Submitting');
  formSubmitBtn.val(loadingText).text(loadingText);
}

function syncCall(){
$.ajax({
    async: false,
    dataType: 'json',
    type: 'GET',
    url: '/calls/synccall',
    success: function (json) {
      userIsSignedIn = json.is_signed_in;
    }
  });
}

我在同步 ajax 调用之前更新 UI 元素。但未显示 UI 更改。当我尝试调试代码时,它工作正常。

【问题讨论】:

  • 尝试使 syncCall 异步 ... setTimeout(syncCall, 0) ... 看看是否有帮助
  • 显示函数的代码。
  • @JaromandaX 在当前情况下无法更改呼叫。
  • 那你有问题
  • 在触发syncCall()之前检查更新的UI元素

标签: javascript jquery ajax jquery-ui asynchronous


【解决方案1】:

我可以想象你的代码正在做类似的事情

var userIsSignedIn;
updateUI(event);
syncCall();
nextThing(userIsSignedIn);
anotherThing();
moreThings();

对 syncCall 进行了简单的更改 - 称为 asyncCall 以防止混淆

function asyncCall(cb){
    $.ajax({
        dataType: 'json',
        type: 'GET',
        url: '/calls/synccall',
        success: function (json) {
          cb(json.is_signed_in);
        }
    });
}

您的代码已重写:

updateUI(event);
asyncCall(function(userIsSignedIn) {
    nextThing(userIsSignedIn);
    anotherThing();
    moreThings();
});

注意缺少var userIsSignedIn; 必需

改善最终用户体验的小改动

第二种选择是将您提供的所有代码包装在标记为async的函数中

async function doThings() {
    updateUI(event);
    let userIsSignedIn = await ajaxCall(); // see below
    nextThing(userIsSignedIn);
    anotherThing();
    moreThings();
}

并从 ajaxCall 返回一个 Promise(syncCall 是什么)

function ajaxCall(){
    return $.ajax({
        dataType: 'json',
        type: 'GET',
        url: '/calls/synccall'
    }).then(json => json.is_signed_in);
}

通过转译器(如 babel)运行此代码,以生成应在 Internet Exploder 和类似的“落后”浏览器上运行的代码

总结:最后你有两个选择

  • 使用 async:false 并获得垃圾用户体验
  • 拥抱异步并编写适合 21 世纪的代码

【讨论】:

    【解决方案2】:

    在发送之前调用这个函数,如下所示

    function syncCall(){
        $.ajax({
        async: false,
        dataType: 'json',
        type: 'GET',
        url: '/calls/synccall',
        beforeSend:function(){
            updateUI(event);// Call here 
        }
        success: function (json) {
          userIsSignedIn = json.is_signed_in;
        }
      });
    }
    

    如果上述方法不起作用,请尝试以下操作

    updateUI(event);
    
    function updateUI(event) {
      formSubmitBtn = $(event.target).find('[type=submit]:not(".disabled")');
      formSubmitBtn.attr('disabled', 'disabled');
      var loadingText = I18n.t('Submitting');
      formSubmitBtn.val(loadingText).text(loadingText);
      syncCall();// Try calling here 
    }
    
    function syncCall(){
    $.ajax({
        async: false,
        dataType: 'json',
        type: 'GET',
        url: '/calls/synccall',
        success: function (json) {
          userIsSignedIn = json.is_signed_in;
        }
      });
    }
    

    【讨论】:

    • ui 更改未显示,但当我在调试模式下执行时,它工作正常。我做了一些搜索,才知道这是同步 ajax 调用的问题,因为它会阻塞 UI。
    • 哦,这里异步是假的
    • 为什么异步是假的
    • 移除 async:false
    猜你喜欢
    • 2016-04-20
    • 1970-01-01
    • 2011-10-06
    • 2012-06-14
    • 2022-10-15
    • 2010-09-14
    • 2012-01-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多