什么是deferred对象
deferred对象是一个延时对象,函数延迟到某个点才开始执行,改变执行状态的方法有两个(成功:resolve和失败:reject),分别对应两种执行回调(成功回调函数:done和失败回调函数fail)
var wait = function() {
var der = $.Deferred();
var test = function(){
console.log("111");
der.resolve("222")
test()
return der
$.when(wait())
.done(function(data){
console.log("执行成功",data)
.fail(function(){
console.log("执行失败")
复制代码
实现
Defferred的实现跟jQuery内部Callbacks函数密不可分
Callbacks源码分析
,要用到其内部的fireWith函数,该函数主要用于控制参数传递以及执行list中的所有回调函数。
Deferred: function(func){
var tuples = [
["resolve", "done", jQuery.Callbacks("once memory")],
["reject", "fail", jQuery.Callbacks("once memory")]
promise = {
then(){
promise(obj){
return obj != null ? jQuery.extend(obj, promise) : promise
deferred = {}
tuples.forEach((tuple, i)=>{
var list = tuple[2]
promise[tuple[1]] = list.add
deferred[tuple[0]] = function(){
deferred[tuple[0] + "With"](this === deferred ? promise : this , arguments)
return this
deferred[tuple[0] + "With"] = list.fireWith
promise.promise(deferred)
return deferred
when(deferred){
return deferred.promise()
复制代码
以上基本能实现deferred对象功能,包含resolve()及reject两个处理函数
deferred对象包含的方法包括 resolve | reject | promise | done | fail | rejectWith | resolveWith
when()函数返回promise对象,其包括的方法有 done | fail | promise
当执行deferred对象的resolve()方法,相当于执行了deferred.resolveWith(),也就是Callbacks里面的fireWith函数,执行Callbacks队列函数的所有回调函数。deferred.resolve() -> deferred.resolveWith() -> list.fireWith() -> list.fire()
回调函数添加进入Callbacks队列函数是通过 promis.done(回调函数) 添加,promise[tuple[1]] = list.add, 由于创建Callbacks传入了memory参数,jQuery.Callbacks("once memory"),它会在添加函数的同时执行Callbacks队列函数
var wait = function() {
var der = $.Deferred();
var test = function(){
console.log("111");
der.resolve("222")
test()
return der
$.when(wait())
.done(function(data){
console.log("执行成功",data)
.fail(function(){
console.log("执行失败")
复制代码
以上便基本实现了Deferred对象,当然Deferred本身还不仅仅是这些,Deferrred最复杂深奥的代码在promise.then里面,本文没有分析,有空再深入