在前端点击按钮,向后端请求数据,在后端计算的过程中,前端会有一个响应界面,我们一般会用一个“正在加载...”的效果。
在Ajax中,有两种请求方式,即异步和同步,默认是异步请求。
在异步请求的时候,向后端请求数据,和当前js页面后面的程序执行是异步的。
而同步执行的时候,后面的js程序,要等到后端数据返回之后,才能继续执行下去。
如果采用同步执行的方式,会导致动态小效果的加载,看不到“正在加载...”的效果。
所以可以采用异步的方式代替。
主要采用jQuery中的Deferred对象,以及其中的一些方法。
详细的原理可以参见:https://javascript.ruanyifeng.com/jquery/deferred.html或者https://www.ruanyifeng.com/blog/2011/08/a_detailed_explanation_of_jquery_deferred_object.html(阮一峰 )
这里摘抄一些原理性的东西,方便记忆:
1. deferred对象代表了将要完成的某种操作(“延迟”的意思),并提供了一些方法。它是jQuery对Promises接口的实现。jQuery的所有Ajax操作函数,默认返回的就是一个deferred对象。
2. Promises是异步操作的通用接口,扮演代理人(proxy)的角色,将异步操作包装成具有同步操作特性的特殊对象。异步操作的典型例子就是Ajax操作、网页动画、web worker等等。
3. 由于JavaScript单线程的特点,如果某个操作耗时很长,其他操作就必需排队等待。为了避免整个程序失去响应,通常的解决方法是将那些排在后面的操作,写成“回调函数”(callback)的形式。这样做虽然可以解决问题,但是有一些显著缺点:
> 回调函数往往写成函数参数的形式,形成所谓的“持续传递风格”(即参数就是下一步操作,Continuation-passing style),导致函数的输入和输出非常混乱,整个程序的可阅读性差;
> 回调函数往往只能指定一个,如果有多个操作,就需要改写回调函数。
> 除了正常的报错机制,错误还可能通过回调函数的形式返回,增加了除错和调试的难度。
> 正常的函数输入和输出可以区分得很清楚,回调函数使得函数的输出不再重要。
Promises就是为了解决这些问题而提出的,它的主要目的就是取代回调函数,成为非同步操作的解决方案。它的核心思想就是让非同步操作返回一个对象,其他操作都针对这个对象来完成。比如,假定ajax操作返回一个Promise对象。
有关Promises对象的使用,可以参见上面的网站。
这里解决问题,主要采用的是Deferred对象将Ajax返回的数据进行封装。在主线程中,采用回调函数的方式,进一步处理返回的数据,以及线程中下面的程序。
具体使用如下:
//主线程
$('.btn').click(function() {
//这里使用layui框架实现动态效果
document.querySelector('.chartes').showLoading({
text: '正在加载数据...'
});
$.when(getData()).done(function(data) {
document.querySelector('.chartes').hideLoading();
alert(data);
});
});
//被调用的Ajax方法
function getData() {
var defer = $.Deferred(); //初始化一个Deferred对象
$.ajax({
url : '',
async : true, // true异步。false同步
success : function(data) {
defer.resolve(data); //resolve表示已完成状态
}
});
//promise()方法表示在原来的deferred对象上返回另一个deferred对象,
//后者只开放与改变执行状态无关的方法(比如done()方法和fail()方法),屏蔽与改变执行状态有关的方法(比如resolve()方法和reject()方法),
//从而使得执行状态不能被改变。
return defer.promise();
}
所以,以上是通过Deferred对象的链式操作得以解决,学习了...
特别注意的是:以上用法只能在jQuery版本高于1.5.0的版本中,因为低于1.5.0,返回的是XHR对象,无法进行链式操作, 而Deferred对象可以进行链式操作。
Deferred对象的链式操作详见阮一峰老师的博客:https://www.ruanyifeng.com/blog/2011/08/a_detailed_explanation_of_jquery_deferred_object.html