제 기술 수준은 일반적으로 제한되어 있습니다. 틀린 부분이 있으면 정정해 주세요.
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"); }) })$.Deferred()는 오늘 소개의 초점입니다. JQ의 지연 객체는 소위 지연이라는 의미로 미래의 특정 기간에 실행될 수 있다는 의미입니다. 위 코드의 처리 흐름을 살펴보겠습니다. 위 코드에서는 새로 생성된 지연 객체의 dfd.done() 메서드의 매개변수 위치에 익명 함수 표현식을 전달하고 클릭 이벤트 핸들러가 다음과 같을 때 dfd를 호출합니다. 그러면 dfd.done()에 작성한 익명 함수가 실행됩니다. 이 과정에서 dfd가 해당 함수를 확인 위치에 배치하는 것을 볼 수 있습니다. dfd는 지연 개체로, 함수의 실행 순서를 분명히 변경할 수 있습니다. 위의 코드를 보시면 잘 생각해보면 유용하다는 것을 알 수 있을 것입니다. 함수에 색상을 변경하는 코드를 넣어두었으니 클릭 시 이 함수를 호출하면 됩니다. 쓰기 그런 고민에는 소용이 있습니다. 실제로 지연된 객체의 가장 일반적인 용도는 AJAX입니다. 위의 코드에서는 add를 클릭한 후, add를 클릭한 후 이번에는 단어가 빨간색으로 바뀌지 않는 것을 발견했습니다. 이는 상태가 변경된 후에는 지연 개체가 무효화되기 때문입니다. 솔직히 말해서 일회용입니다. 지연 객체 사용 JQ는 일반적으로 Deferred 또는 Promise라고 부르는데, 정확히 말하면 Promise는 Deferred에서 파생됩니다. 아강. 이를 사용할 때 먼저 지연된 개체(var dfd = new $.Deferred())를 만듭니다. 지연된 객체 dfd에는 보류, 해결, 거부의 세 가지 상태가 있습니다. 이때 dfd 객체의 상태 메서드인 dfd.state()를 사용하여 상태를 확인할 수 있습니다. dfd가 생성된 후 해당 상태는 확인 메서드(dfd.resolve())를 호출한 후 확인되고 dfd.done()의 함수가 거부됩니다. dfd.reject() 메소드 이후에는 상태가 거부됨으로 변경되고 dfd.fail()의 메소드가 실행되며, 보류 중에서 해결됨 또는 거부됨으로 변경된 후에도 dfd 객체가 변경되지 않습니다. 위의 코드는 첫 번째 클릭 후에만 텍스트를 빨간색으로 만들 수 있습니다.
시작 코드를 살펴보겠습니다. dfd.done()은 클릭 함수에서 글꼴을 빨간색으로 만드는 함수를 정의합니다. 실행 후 dfd 호출이 해결됩니다. dfd 상태가 보류 중에서 해결됨으로 변경된 후 done의 메서드가 실행되고 색상이 빨간색으로 변합니다.
dfd.resolve()와 dfd.done() 사이에 매개변수를 전달할 수 있습니다. 이제 시작 코드를 일부 수정합니다.
클릭하면 글꼴 색상이 녹색으로 변경됩니다.
//done里面的修改如下 dfd.done(function(color){$("span").css("color",color)}) //点击事件的处理函数修改如下 dfd.resolve("green");게다가 dfd에는 Always라는 또 다른 함수가 있습니다: dfd.always(). Always의 함수는 dfd의 상태가 보류 중으로 변경될 때마다 실행됩니다. dfd의 각 메소드는 지연 객체를 반환하므로 여러 개의 done, failure 및 Always가 있을 수 있으며 체인 호출로 직접 작성할 수 있습니다. dfd.done(function( ){}).done(function(){}).fail(function(){});
dfd의 어떤 API이든 현재로서는 여러 API를 작성할 수 있습니다. 실행 순서가 보장될 수 있는가? dfd의 함수 실행 순서는 우리가 작성한 순서대로 실행되므로 안심하셔도 됩니다.
첫 번째 코드를 살펴보세요. 함수는 요소를 추가하고, 두 번째 함수는 추가된 요소의 색상을 변경합니다.
dfd.done(function(){ var span = $("<span>我是点击按钮创建的元素</span>"); $("span").length==0&&$("body").append(span); }) .done(function(color){ $("span").css("color",color)}); })dfd의 상태가 보류 중에서 변경된 후에만 dfd의 세 가지 API에 있는 함수를 실행할 수 있는 경우 이는 비동기식 경우와 동기식 경우 모두 마찬가지입니다. 더 정확하게 말하면 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,3JQ의 AJAX를 처음 사용했을 때 일반적인 작성 방법은 다음과 같습니다.
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()就可以一直调用,同样也可以传递参数。