使用async的Chrome和Safari ajax问题:false

时间:2017-01-17 13:10:12

标签: jquery ajax google-chrome

我在网上到处都看到了这个,但我无法修复我的代码以避免这个问题,只是我有一个ajax函数,当我点击一些按钮时触发,有时我想要一个指示器(加载动画)到显示,有时不是,所以我建立我的功能:

function doAjax(action, todo, items, error_num, hide_indicator) {
  items.action = action;
  items.do = todo;
  var postedObj;

  $.ajax({
    type: 'post',
    dataType: 'html',
    url: ajaxURL,
    data: items,
    async: false,
    beforeSend: function() {
      if (!hide_indicator) showIndicator();
    },
    success: function(data) {
      if (data) {
        ajaxObj = JSON.parse(data);
        if (ajaxObj.ok) {
          postedObj = ajaxObj;
        } else {
          alert(ajaxObj.error);
          postedObj = false;
        }
      } else {
        alert('[' + error_num + '] Something went wrong.');
        postedObj = false;
      }
      if (!hide_indicator) hideIndicator();
    },
    error: function() {
      alert('[' + error_num + '] Something went wrong.');
      postedObj = false;
      if (!hide_indicator) hideIndicator();
    }

  });
    return postedObj;
}

以下是我在按钮上执行的操作:

$(document).on('click', '.ad-single', function() {
  var addataObj = doAjax('post_requests', 'get-ad-info', {"id": $(this).data('ad')}, '158', false); // false means DON'T hide the indicator
  if (addataObj) {
    loadContent(addataObj.ad);
  }  
});

好了,现在,一切都按预期在Firefox上运行,当我点击我的按钮时,指示器显示并等待ajax返回数据,然后再次隐藏指示器。

这在Chrome和Safari上不起作用,该功能正常工作并按预期返回数据但似乎立即调用hideIndicator()函数,我不知道如何解决这个问题。

火狐:

enter image description here

Chrome和Safari:

enter image description here

1 个答案:

答案 0 :(得分:3)

使用async: false是邪恶的。互联网上充满了这样的帖子,包括Chrome和Safari在内的许多浏览器都会在发出同步AJAX请求时给出很多警告。

幸运的是,jQuery的承诺可以用来克服你的问题。它不会改变你的函数的工作方式,也会利用promises的功能来发出异步请求。

您可以按如下方式修改现有函数,以便它返回AJAX承诺,而不是结果。

function doAjax(action, todo, items, error_num, hide_indicator) {
  items.action = action;
  items.do = todo;

  return $.ajax({
      type: 'post',
      dataType: 'html',
      url: ajaxURL,
      data: items,
      beforeSend: function() {
        if (!hide_indicator) showIndicator();
      }
    })
    .then(function(data) {
      if (!hide_indicator) {
        hideIndicator();
      }

      if (data) {
        ajaxObj = JSON.parse(data);

        if (ajaxObj.ok) {
          return ajaxObj;
        }

        alert(ajaxObj.error);
        return false;
      }

      alert('[' + error_num + '] Something went wrong.');
      return false;
    }, function() {
      if (!hide_indicator) {
        hideIndicator();
      }

      alert('[' + error_num + '] Something went wrong.');
      return false;
    });
}

这里,.then函数可用于预处理响应,并将适当的值返回给后续的promise处理程序。

后续的promise处理程序可以如下实现,它调用doAjax函数,并通过预处理对值返回作出反应。

$(document).on('click', '.ad-single', function() {
  doAjax('post_requests', 'get-ad-info', {"id": $(this).data('ad')}, '158', false)
    .then(function(addataObj) {
      if (addataObj) {
        loadContent(addataObj.ad);
      }
    });
});

此处,.then()与之前的.then()相关联,并对返回的值做出反应(在addataObj中收到)。请注意,它只对AJAX调用的成功做出反应。如果您还想处理错误响应,则需要将第二个参数作为函数传递给.then()处理程序。

希望这能解决你的问题。