제 기술 수준은 일반적으로 제한되어 있습니다. 틀린 부분이 있으면 정정해 주세요.
ES6에서는 지연된 개체 Promise를 구현했지만 오늘날 주인공은 JQ의 지연된 개체이며 루틴은 실제로 동일합니다. 다소 터무니없는 예를 살펴보겠습니다.
<button id="add">add</button><button id="remove">remove</button> <div id="content"></div>
스팬 요소에 추가하고 색상을 빨간색으로 변경합니다. 그런 다음 코드의 이질적인 내용을 살펴보았습니다. 시작 var dfd = new $.Deferred() 및 add 이벤트 함수의 dfd.done(function(){ $(" 범위").css("색상","빨간색");}).
$(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"); }) })
시작 코드를 살펴보겠습니다. dfd.done()은 클릭 함수에서 글꼴을 빨간색으로 만드는 함수를 정의합니다. 실행 후 dfd 호출이 해결됩니다. dfd 상태가 보류 중에서 해결됨으로 변경된 후 done의 메서드가 실행되고 색상이 빨간색으로 변합니다.
dfd.resolve()와 dfd.done() 사이에 매개변수를 전달할 수 있습니다. 이제 시작 코드를 일부 수정합니다.
클릭하면 글꼴 색상이 녹색으로 변경됩니다.
//done里面的修改如下 dfd.done(function(color){$("span").css("color",color)}) //点击事件的处理函数修改如下 dfd.resolve("green");
dfd의 어떤 API이든 현재로서는 여러 API를 작성할 수 있습니다. 실행 순서가 보장될 수 있는가? dfd의 함수 실행 순서는 우리가 작성한 순서대로 실행되므로 안심하셔도 됩니다.
첫 번째 코드를 살펴보세요. 함수는 요소를 추가하고, 두 번째 함수는 추가된 요소의 색상을 변경합니다.
dfd.done(function(){ var span = $("<span>我是点击按钮创建的元素</span>"); $("span").length==0&&$("body").append(span); }) .done(function(color){ $("span").css("color",color)}); })
지연된 객체 예
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
1.5 이후(이 버전인 것 같아요~) AJAX는 Promise 객체를 반환하는데, 다음과 같이 작성하면 됩니다.
$.ajax({ url:"x/y", type:"post", data:"{...}", contentType:"application/json; charset=utf-8", success:function(){}, error:function(){} })
좀 더 공격적으로 보이고 여러 개의 .done(function(){})을 추가할 수도 있습니다. 각 완료는 서로 다른 작업을 처리하므로 더 명확해 보입니다.
已经知道延迟对象可以改变代码的执行顺序,假如我们又下面的代码:
$.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()就可以一直调用,同样也可以传递参数。