Home > Article > Web Front-end > jquery deferred object use case
This time I will bring you a jquery delayed object usage case. What are the precautions for using jquery delayed object. The following is a practical case, let’s take a look.
The technical level is generally limited. If there are any mistakes, please correct me.
ES6 has implemented delayed object Promise, but today’s protagonist is the delayed object in JQ, and the routines are actually the same. Let's take a look at a far-fetched example:
<button id="add">add</button><button id="remove">remove</button> <p id="content"></p>
$(function(){ var dfd = new $.Deferred(); var add = $("#add"); var remove = $("#remove"); var content = $("#content"); add.click(function(){ var span = $("<span>我是点击按钮创建的元素</span>"); $("span").length==0&&$("body").append(span); dfd.resolve(); }) remove.click(function(){ var span = $("span"); span&&span.remove(); }) dfd.done(function(){ $("span").css("color","red"); }) })
Now focus on the function. When we click the add button, we can see that the span element is added and the color turns red. Then we looked at the heterogeneous things in our code, the beginning var dfd = new $.Deferred(); and the dfd.resolve() in the add event function; and the last dfd.done(function(){ $("span").css("color","red");}).
$.Deferred() is the focus of our introduction today---the delay object in JQ. The so-called delay means that it can run in a certain period of time in the future. Let’s look at a processing flow of the above code. In the above code, we call the dfd.done() method of the newly created delayed object and pass an anonymous function expression in the parameter position. In the processing of the click event When the function is executed, dfd.resolve() is called, and then the anonymous function we wrote in dfd.done() is executed. In this process, we can see that dfd puts the function in done in resolve position. dfd is a delay object, which obviously can change the execution order of functions.
When you look at the above code, if you think about it carefully, you will find that it is useful. We put the code that changes the color in a function, and call this function when clicked That's not great. It's so troublesome to write. In fact, the most common use of deferred objects is in AJAX. In the above code, after we click add, we click remove and then click add. At this time, we find that the word does not turn red this time. This is because the delayed object becomes invalid after the state changes. To put it bluntly, it is a one-time use.
Use of delayed objects
JQ implements the function of delayed objects for us. We generally call it Deferred or Promise, which is basically the same thing. To be precise, Promise is A subclass derived from Deferred.
When we use it, we first create a deferred object: var dfd = new $.Deferred().
The delayed object dfd has three states: pending, resolved, and rejected. We can check the state at this time by using the state method on the dfd object: dfd.state().
After dfd is created, its status is pending. After calling the resolve method: dfd.resolve(), its status will change to resolved and then the function in dfd.done() will be executed. dfd calls reject. After the method: dfd.reject(), its status will change to rejected and then the method in dfd.fail() will be executed, and the dfd object will not change after changing from pending to resolved or rejected. This That's why our code above can only make the text red after the first click.
Let’s take a look at the starting code. Our dfd.done() defines a function that turns the font red. After clicking on the function to execute, dfd calls resolve. After the status of dfd changes from pending to resolved, the method in done will be executed and the color will turn red.
Parameters can be passed between dfd.resolve() and dfd.done(). Now we make some modifications to the initial code:
//done里面的修改如下 dfd.done(function(color){$("span").css("color",color)}) //点击事件的处理函数修改如下 dfd.resolve("green");
We change the font color after clicking For green.
In addition, dfd has another function always: dfd.always(). The functions in always will be executed whenever the status of dfd changes from pending.
Each method of dfd will return a delay object, so there can be multiple done, fail, and always, which can be written directly as a chain call:
dfd.done (function(){}).done(function(){}).fail(function(){});
No matter which API of dfd, you can write multiple ones. At this time, we will You may consider whether its execution order can be guaranteed. We can rest assured that the order in which dfd's functions are executed is absolutely no problem and will be executed in the order we wrote it. Look at the following code:
dfd.done(function(){ var span = $("<span>我是点击按钮创建的元素</span>"); $("span").length==0&&$("body").append(span); }) .done(function(color){ $("span").css("color",color)}); })
The first function adds elements, and the second function changes and adds The color of the element.
无论什么时候dfd三个API里面的函数都会在dfd的状态从pending变化之后才能执行,在异步的情况下如此,在同步的情况下也是。更确切的说dfd在调用dfd.resolve()之后已经执行过的done的里面的函数会立即执行,对于dfd.resolve()后面的done来说当程序走到它那时才会执行:
var dfd = new $.Deferred(); dfd.done(function(){console.log(1)}); dfd.done(function(){console.log(2)}); console.log("resolve before"); dfd.resolve(); console.log("resolve after"); dfd.done(function(){console.log(3)}); //resolve before,1,2,resolve after,3
延迟对象示例
最开始我们使用JQ的AJAX的时候我们通常的写法是:
$.ajax({ url:"x/y", type:"post", data:"{...}", contentType:"application/json; charset=utf-8", success:function(){}, error:function(){} })
在1.5(好像是这个版本~)之后AJAX会返回一个Promise对象,继而我们可以写成下面这种:
$.ajax({ url:"x/y", type:"post", data:"{...}", contentType:"application/json; charset=utf-8", }).done(function(){}) .fail(function(){})
看起来更骚气了一点,而且这我们还可以在加多个.done(function(){}),每个done处理不同的事情这样看起来比较清晰。
已经知道延迟对象可以改变代码的执行顺序,假如我们又下面的代码:
$.ajax({ url:"取数据", type:"post", contentType:"xxx" }).done(function(data){ $.ajax({ url:"利用data取数据", data:data, type:"post", contentType:"xxxx" }).done(function(data){ use data to _do sth... }) })
我们会发现嵌套的有点多了,我们就可以利用延迟对象让他看起来更加好看一点:
var dfd = new $.Deferred(); $.ajax({ url:"取数据", type:"post", contentType:"xxx" }).done(function(data){ dfd.resolve(data); }) dfd.done(function(data){ $.ajax({ url:"利用data取数据", data:data, type:"post", contentType:"xxxx" }).done(function(data){ use data to _do sth... }) })
没有延迟对象我们一样能完成需要的功能,此时我们就需要一层一层嵌套我们处理过程了,而有了延迟对象我们就可以避免这种事了,他可以轻松控制代码的执行顺序,让代码看起来更请清晰。你可能会说我封装函数在合适的地方调不就行了,如果自己看自己写的代码没问题,但是换一个人他的滚动条可能就一直上上下下了。
延迟对象的里一个作用就是可以合并AJAX的调用,比如一个接口取数据A另一个接口取数据B,AB都取到之后我们在利用这些数据做一些喜欢做的事,我们就可以利用延迟对象轻松实现。此时我们就可以利用JQ的$.when()来实现。$.when()就跟他的名字一样-当什么的时候-,他的参数可以是Promise对象,也可以是字符串(很少遇到不在介绍),他的返回结果也是一个Promise对象,下面看一个小例子:
var allData = {}; var dataA = $.ajax({ url:"获取A的URL", type:"post", }).done(function(data){ allData.a = data; }); var dataB = $.ajax({ url:"获取B的URL", type:"post", }).done(function(data){ allData.b = data; }); $.when(dataA,dataB).done(function(){ use allData to _do sth... });
allData是保存所有数据的一个集合,dataA是第一个AJAX返回的Promise对象,dataB是第二个。$.when()的done方法执行的唯一条件就是dataA和dataB都执行成功。
补充:dfd还有一对组合就是notify+progress当dfd对象的状态处于pending时可以调用dfd.nothfy(),调用之后dfd.progress()里面的函数会执行,只要dfd处于pending状态dfd.notify()就可以一直调用,同样也可以传递参数。
相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!
推荐阅读:
The above is the detailed content of jquery deferred object use case. For more information, please follow other related articles on the PHP Chinese website!