jQuery(五): Deferred

有啥用

通常来说,js请求数据,无论是异步还是同步,都不会立即获取到结果,通常而言,我们一般是是使用回调函数再执行,而 deferred就是解决jQuery的回调函数方案,总的来说,deferred对象就是为了将某个回调函数延迟到某个时机再执行.

  1. ajax链式写法:

      //一般写法:
    $.ajax({
    url: '',
    success: function(){},
    error: function(){},
    }) //deferred
    $.ajax(url)
    .done(function(){}) //相当于success
    .fail(function(){})
  2. 指定同一操作的多个函数,允许添加多个函数

    写法也很简单,直接添加在后面就可以了。

     $.ajax(url)
    .done(function(){})
    .fail(function(){})
    .done(function(){})
  3. 为多个函数添加指定回调,可以为多个不同的函数添加同一个回调事件

      $.when($.ajax(url),$.ajax(url2))
    .done()
    .fail()

    为两个函数执行操作,如果都成功了就执行done中的回调,如果有一个失败或全部都失败,就执行fail中的回调

  4. 普通操作的回调

    deferred允许任何操作都可以使用deferred对象的方法,指定回调函数

     var wait = function(de){
    var test = function(){
    console.log('开始');
    de.resolve();
    }
    setTimeout(test, 3000);
    return de;
    } $.when(wait($.Deferred()))
    .done(function(){
    console.log('已完成')
    })
    .fail(function(){
    console.log('失败')
    })

注意: $.when()的参数只能是deferred对象。

咋处理

  1. 关于resolve && rejected

    在上面的时候,会注意到一个resolve,并且会觉得这种链式写法很眼熟,且对promise有一个简单了解的话,大概就知道了。

       promise: 同样也是用于处理异步函数,将异步操作队列化处理
    
       简单的promise
    new promise (function(resolve,rejected){
    resolve('成功')
    })
    .then(function(){}) promise.then 接受两个参数:
    一、 resolve 代表成功时调用的函数
    二、 rejected 代表失败时调用的回调
    promise的三个状态值: pending(初始状态值), fulfilled(操作成功),rejected(操作失败)

    $.deferred 同样也是有三个不同的状态:未完成,已完成,已失败,当状态处于已完成(resolve)下回自动调用done()中的回调函数,而resolve()就是人为将状态值修改为已完成,同理可证rejected();

    总的来说,核心就是:根据不同的状态值调用回调。

  2. API

    * $.Deferred()

    * $.when()

    * deferred.progress()

    * deferred.promise()

    * deferred.done()

    * deferred.fail()

学习下

来看下jQ的源码是怎么处理的:

    Deferred: function(func) {
var tuples = [
// action, add listener, callbacks,
// ... .then handlers, argument index, [final state]
["notify", "progress", jQuery.Callbacks("memory"),
jQuery.Callbacks("memory"), 2
],
["resolve", "done", jQuery.Callbacks("once memory"),
jQuery.Callbacks("once memory"), 0, "resolved"
],
["reject", "fail", jQuery.Callbacks("once memory"),
jQuery.Callbacks("once memory"), 1, "rejected"
]
],
state = 'pending', // 延迟对象
deferred = {},
promise = {
state: function() {
return state
},
then: function(){},
promise: function(obj) {
return obj != null ? jQuery.extend(obj, promise): promise;
}
}
...
}

从代码来看,定一个了数组tuples,以及初始状态值。tuples存储了三个状态下的所需参数,来看下存储了写什么内容:

[状态, 对应的处理函数, 利用callbacks创建的回调队列, then方法的回调队列, index, 最终的状态值],

我们可以看到最终的状态值只有reject 和resolve才有。

ok,已经知道deferred的本质是根据不同的状态调用不同的方法,并且使用callbacks添加函数,那么把tuples遍历一下,生成队列;

源码:

    tuples.forEach(function(tuple){
var list = tuple[2], // 获取到jQuery.callbacks返回,创建一个队列
stateString = tuple[5], //获取到最终状态描述 //promise[ progress | done | fail ] = list.add
promise[tuple[1]] = list.add; // 如果最终状态值存在,即处于 reject|| resolve 状态下;
if (stateString) {
list.add(
function() {
state = stateString;
}
....
)
}
// 延迟对象状态 deferred.resolve()
//deferred[ 'resolve' | reject | notify] = function(){} deferred[tuple[0]] = function() {
deferred[tuple[0]+"Width"](this === deferred ? promise : this, arguments);
return this;
} //jQuery.callbacks.fireWith
//执行队列,调用处理函数,绑定执行时的上下文
deferred[tuple[0] + "With"] = list.fireWith;
})
promise.promise(deferred);
return deferred;

已经遍历生成了3个队列,并将三个状态方法挂载在了延迟对象上。

从代码中可以看出,在调用deferred[ reject | resolve]时,其实是调用了deferred[ rejectWith | resolveWith]方法,本质上是对callbacks.fireWith的调用,以用来执行添加的回调函数,同时设置函数的上下文。

并且可以看的到,deferred[proress | done | fail] 其实是copy了callbacks.add方法,将回调函数添加在了执行队列中。

另外关于对jQuery.deferred对象的详解,使用,https://www.cnblogs.com/chris-oil/p/8922770.html 这篇博文转载了阮大神的,可以瞅瞅

jQuery(五): Deferred的更多相关文章

  1. jQuery之Deferred源码剖析

    一.前言 大约在夏季,我们谈过ES6的Promise(详见here),其实在ES6前jQuery早就有了Promise,也就是我们所知道的Deferred对象,宗旨当然也和ES6的Promise一样, ...

  2. jQuery的deferred对象详解(一)

    最近一段时间,都在研究jquery里面的$.Deffered对象,几天都搞不明白,其中源码的运行机制,网上查找了相关的资料,<jQuery的deferred对象详解>阮一峰老师的文章,里面 ...

  3. [转] jQuery的deferred对象详解

    jQuery的开发速度很快,几乎每半年一个大版本,每两个月一个小版本. 每个版本都会引入一些新功能.今天我想介绍的,就是从jQuery 1.5.0版本开始引入的一个新功能----deferred对象. ...

  4. jQuery的deferred对象详解(转)

    jQuery的开发速度很快,几乎每半年一个大版本,每两个月一个小版本. 每个版本都会引入一些新功能.今天我想介绍的,就是从jQuery 1.5.0版本开始引入的一个新功能----deferred对象. ...

  5. jQuery的deferred对象详解 jquery回调函数

    http://www.ruanyifeng.com/blog/2011/08/a_detailed_explanation_of_jquery_deferred_object.html jQuery的 ...

  6. jQuery的deferred对象详解(转载)

    jQuery的开发速度很快,几乎每半年一个大版本,每两个月一个小版本.(由于无法转载,复制原文 .原文链接——原作者:阮一峰) 每个版本都会引入一些新功能.今天我想介绍的,就是从jQuery 1.5. ...

  7. 【转】jQuery的deferred对象详解

    jQuery的开发速度很快,几乎每半年一个大版本,每两个月一个小版本. 每个版本都会引入一些新功能.今天我想介绍的,就是从jQuery 1.5.0版本开始引入的一个新功能----deferred对象. ...

  8. jQuery的deferred对象详解(转)

    jQuery的开发速度很快,几乎每半年一个大版本,每两个月一个小版本. 每个版本都会引入一些新功能.今天我想介绍的,就是从jQuery 1.5.0版本开始引入的一个新功能----deferred对象. ...

  9. (转)jQuery的deferred对象详解

    作者: 阮一峰 日期: 2011年8月16日 jQuery的开发速度很快,几乎每半年一个大版本,每两个月一个小版本. 每个版本都会引入一些新功能.今天我想介绍的,就是从jQuery 1.5.0版本开始 ...

随机推荐

  1. Win10下默认显示文件的扩展名

    默认不显示文件的后缀名 1.右击此电脑,点击属性 2.点击控制面板主页 3.点击文件资源管理器选项 4.切换到查看选项卡,取消勾选“隐藏已知文件类型的扩展名”,应用->确定 结果:

  2. Python并发编程之进程通信

    ''' 进程间的通信 ''' """ multiprocessing模块支持进程间通信的两种主要形式:管道和队列 都是基于消息传递实现的, ""&qu ...

  3. 使用面向对象思想封装js(附实例)

    平时在写js时应该用面向对象思想将每一组功能封装成一个模块,可实现模块间的高内聚低耦合.重用.结构清晰........... 如果页面中逻辑复杂.功能多,不使用模块封装是不可想象的,维护起来非常复杂. ...

  4. Django 1.11 网站分页设计

    参考网址:https://www.cnblogs.com/kongzhagen/p/6640975.html

  5. LOJ2687 BOI2013Vim 题解

    题目链接 这里只写个摘要,具体的可以看 神仙Itst的博客 大概是每相邻两个位置之间的线段要么被覆盖一次,要么被覆盖三次,然后DP,如下图: 代码: #include<bits/stdc++.h ...

  6. web服务本质

    目录 django 框架引入: web框架本质 HTTP协议 多功能web服务 封装,分发处理 django 框架引入: web框架本质 web框架本质: 软件开发架构: c / s ; b/ s - ...

  7. awesome-RecSys

    https://github.com/jihoo-kim/awesome-RecSys?fbclid=IwAR1m6OebmqO9mfLV1ta4OTihQc9Phw8WNS4zdr5IeT1X1OL ...

  8. 记一次Pr中视频蜜汁卡顿往复和解决方法

    目录 问题 换素材的起因 灵异素材 无端联想 解决 问题 换素材的起因 本来视频剪了一晚剪完了,导出一看,好家伙,糊到上世纪.原来素材的像素大小都没法看,这视频素材我是从别人U盘拷过来的,可他竟然是用 ...

  9. OCR识别的Android端实现

    1.OCR简介OCR (Optical Character Recognition,光学字符识别)是指电子设备(例如扫描仪或数码相机)检查纸上打印的字符,通过检测暗.亮的模式确定其形状,然后用字符识别 ...

  10. ORM之Entity Framework(EF)

    ORM之Entity Framework(EF) 一.下载安装: nuget 搜索Entity Framework安装 EntityFramework.Extension是个扩展库根据需要安装 二.使 ...