javascript --- jQuery --- Deferred对象

javascript的函数式编程是多么引人入胜,
jQuery使代码尽可能的精简,intelligent!

defer - 必应词典:v.迁延;听从;扣存;【军】使延期入伍
所以deferred对象的含义就是"延迟"到未来某个点再执行。

jQuery的官方文档给出了用jQuery.ajax()发送请求的基本方式
http://api.jquery.com/jQuery.ajax/
Example: Save some data to the server and notify the user once it's complete.

服务端需要接收数据,这里为了方便起见,我们请求一个静态文件sample.html
sample.html的内容如下:
\jQuery_Deferred\sample.html

<!DOCTYPE html>
<html>
<body>
    Ajax请求返回的数据!
</body>
</html>

这里的ajax方法请求的是静态文件sample.html
\jQuery_Deferred\deferred1.html

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>Ajax Example</title>
    <script src="jquery-2.1.1.js"></script>
</head>
<body>
<script>
    $.ajax({
        type: "POST",
        url: "sample.html",
        data: { name: "John", location: "Boston" }
    }).done(function (msg) {
        alert("Data Saved: " + msg);
    });
</script>
</body>
</html>

用浏览器打开后,可以看到如下的结果:picture

本文参考了阮一峰的日志:
http://www.ruanyifeng.com/blog/2011/08/a_detailed_explanation_of_jquery_deferred_object.html
deferred对象彻底改变了在jQuery中使用ajax
如果对ajax陌生,可以参考我以前写的日志:
http://www.cnblogs.com/kodoyang/p/Javascript_Ajax_XMLHttpRequest_Encapsulation.html

deferred对象就是jQuery的回调函数解决方案
下面是阮一峰博客的原文:

{
开发网站的过程中,我们经常遇到某些耗时很长的javascript操作。
  其中,既有异步的操作(比如ajax读取服务器数据),
  也有同步的操作(比如遍历一个大型数组),它们都不是立即能得到结果的。
通常的做法是,为它们指定回调函数(callback)。
  即事先规定,一旦它们运行结束,应该调用哪些函数。
  它解决了如何处理耗时操作的问题,
  对那些操作提供了更好的控制,以及统一的编程接口。
}

jQuery的ajax的传统写法如下:
jQuery的在线API 文档: http://jquery.cuishifeng.cn/
\jQuery_Deferred\deferred2.html

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>Traditional Ajax</title>
    <script src="jquery-2.1.1.js"></script>
</head>
<body>
<script>
    $.ajax({
        url: "test.html",
        context: document.body,
        success: function () {
            $(this).addClass("done");
        }
    });
</script>
</body>
</html>

\jQuery_Deferred\test.html

<p>
success data!
</p>

使用Deferred对象的链式操作,写法如下:
\jQuery_Deferred\deferred3.html

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>Deferred Ajax</title>
    <script src="jquery-2.1.1.js"></script>
</head>
<body>
    <script>
        $.ajax("test1.html")
                .done(function(data){
                    alert(data);
                })
                .fail(function(){
                    alert("error!");
                });
    </script>
</body>
</html>

这里$.ajax()返回的是deferred对象

deferred对象允许自由添加多个回调函数
\jQuery_Deferred\deferred4.html

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>Deferred add callback function</title>
    <script src="jquery-2.1.1.js"></script>
</head>
<body>
<script>
    $.ajax("test.html")
            .done(function(data){
                alert(data);
            })
            .fail(function(){
                alert("error!");
            })
            .done(function(){
                alert("haha, success!");
            });
</script>
</body>
</html>

deferre对象允许为多个事件指定一个回调函数
当两个操作都返回成功时,运行done()指定的回调函数

\jQuery_Deferred\deferred5.html

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>above one request</title>
    <script src="jquery-2.1.1.js"></script>
</head>
<body>
<script>
    $.when($.ajax("test.html"), $.ajax("sample.html"))
            .done(function(){
                alert("哈哈,成功了!");
            })
            .fail(function(){
                alert("出错啦!");
            });
</script>
</body>
</html>

使用普通操作的回调函数接口
\jQuery_Deferred\deferred6.html

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>general function</title>
    <script src="jquery-2.1.1.js"></script>
</head>
<body>
<script>
    var wait = function(){
        setTimeout(function(){
            alert("执行完毕!");
        }, 5000);
    }
</script>
</body>
</html>

我们应该怎样为它指定回调函数?
$.ajax返回的是deferred对象,所以可以链式调用

具体的细节可以查看阮一峰的日志,我这里给出最后的写法:
\jQuery_Deferred\deferred7.html

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>final code</title>
    <script src="jquery-2.1.1.js"></script>
</head>
<body>
<script>
    /**
     * Deferred对象有三种执行状态:
     * 未完成:
     *      继续等待,或者调用progress()方法指定的回调函数
     * 已完成:
     *      deferred.resolve() 调用后
     *      deferred对象立刻调用done()方法指定的回调函数
     * 已失败:
     *      deferred.reject() 调用后
     *      调用fail()方法指定的回调函数
     *
     * Deferred.promise函数:
     *      避免Deferred对象的“执行状态”在外部发生改变
     *      它的作用是,在原来的deferred对象上返回另一个deferred对象,
     *      后者只开放与改变执行状态无关的方法(比如done()方法和fail()方法),
     *      屏蔽与改变执行状态有关的方法(比如resolve()方法和reject()方法),
     *      从而使得执行状态不能被改变。
     *
     * @returns 不能改变执行状态的Deferred对象
     */
    function wait(){
        // 在函数内部,新建一个Deferred对象
        var deferred = $.Deferred();
        setTimeout(function(){
            alert("执行完毕!");
            // 改变Deferred对象的执行状态
            deferred.resolve();
        }, 5000);
        // 返回promise对象
        return deferred.promise();
    }

    /**
     * 接受一个Deferred对象,
     * 当检测到对象的执行状态发生改变后,调用相应的函数
     */
    $.when(wait())
            .done(function(){
                alert("hahah, 成功了!");
            })
            .fail(function(){
                alert("aaouu,出错了!")
            });
</script>
</body>
</html>

最后介绍一下Deferred.alway()函数
不管调用的是deferred.resolve()还是deferred.reject(),最后总是执行。
\jQuery_Deferred\deferred8.html

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>reject then always</title>
    <script src="jquery-2.1.1.js"></script>
</head>
<body>
<script>
    /**
     * 这个方法也是用来指定回调函数的,它的作用是,
     * 不管调用的是deferred.resolve()还是deferred.reject(),
     * 最后总是执行。
     */
    $.when($.ajax("test1.html"))
            .always(function(data){
                alert("已执行:" + data);
            });
</script>
</body>
</html>

请关注我的日志:http://www.cnblogs.com/kodoyang/

For Better Programming!

javascript --- jQuery --- Deferred对象的更多相关文章

  1. jQuery.Deferred对象

    一.前言 jQuery1.5之前,如果需要多次Ajax操作,我们一般会使用下面的两种方式: 1).串行调用Ajax $.ajax({ success: function() { $.ajax({ su ...

  2. JQuery Deferred 对象

    http://www.ruanyifeng.com/blog/2011/08/a_detailed_explanation_of_jquery_deferred_object.html <jQu ...

  3. 使用JQuery Deferred对象的then() 解决多个AJAX操作顺序依赖的问题

    原文地址:http://www.2cto.com/kf/201507/424202.html 之前的文章javascript异步代码的回调地狱中提到了编写AJAX代码经常遇到的3个问题,现在我们看下如 ...

  4. jQuery Deferred对象详细源码分析(-)

    本系列文章讲介绍这个Deferred东西到底拿来干什么,从1.5版本加进来,jQuery的很多代码都重写了.直接先上源码分析了,清楚了源码分析,下节将讲具体的应用 以及应用场景. 创建对象 var d ...

  5. JQuery Deferred 对象剖析

    JQuery 中利用 Deferred 对象提供类似 ES2016(aka. es7) 中 Promise 的功能. JQuery 中的 AJAX 请求函数返回的就是 Deferred 对象. 通过使 ...

  6. javascript jquery封装对象时的错误,求解!我想知道为什么

    jquery   封装对象时的错误 --------------------------------------------<input id="name" name=&qu ...

  7. JQuery Deferred对象使用小结

    场景描述 如下,打开页面时,获取默认选中的项目,同时也会初始化Combobox下拉框下拉列表数据 问题描述 获取默认选中项目及下拉列表的js函数位于common.js文件,类似如下: // 根据项目类 ...

  8. javascript jquery 推断对象为空的方式

    java中存在非常多空指针的问题,须要常常做预防和推断,如若不然,控制台出现恼人的异常,让人信心备受打击,早期敲代码的时候没有经验,不能依据异常信息找到问题的根源,唯一做的事情就是祈祷,千万别出现什么 ...

  9. 利用 Jquery Deferred 异步你的程序

    最近在做公司QA系统改造时,有这样的一个场景. QA系统中有些数据项需要从JIRA平台(一个国外项目与事务跟踪工具)中获取,JIRA平台提供了很完善的Rest API. 现在的要求是,在QA系统中提交 ...

随机推荐

  1. (译) Angular运行原理揭秘 Part 1

    当你用AngularJS写的应用越多, 你会越发的觉得它相当神奇. 之前我用AngularJS实现了相当多酷炫的效果, 所以我决定去看看它的源码, 我想这样也许我能知道它的原理. 下面是我从源码中找到 ...

  2. INDIGO STUDIO神器!快速创建WEB、移动应用的交互原型工具【转】

    转自:http://www.uisdc.com/indigo-studio-wireframe-interactive-uis 这套最新的设计工具出自Indigo工作室,永久免费,有mac版本和WIN ...

  3. 《c程序设计语言》读书笔记--反转字符串

    #include "stdio.h" #define Num 100 void reverse(char words[]) { int i, j, c, n=0; while(wo ...

  4. 浅析JavaScript之Function类型

    JavaScript中的函数实际上是对象,每个函数都是Function类型的实例,而且都与其他引用类型一样具有属性和方法.由于函数是对象,因此函数名实际上只是指向函数对象的指针,保存函数在堆内存中的地 ...

  5. Couchbase 找回登录密码

    在项目里,我们使用Couchbase当做缓存层,效果非常好,支持集群与数据监测,可悲的有一次我新建了一个服务器,安装完成Couchbase之后,密码忘了! 怎么也想不起来,Couchbase又没有提供 ...

  6. vmware装redhat该光盘无法被挂载

    为了考网工,没办法只能学学linux了,前天在vmware7装redhat 提示该光盘无法被挂载,还以为是光盘错误,换了N个盘,又装了很多次,最后观察到,换了盘之后点确定,里面就提示该光盘无法被挂载, ...

  7. WCF常见异常-The maximum string content length quota (8192) has been exceeded while reading XML data

    异常信息:The maximum string content length quota (8192) has been exceeded while reading XML data 问题:调用第三 ...

  8. 【第一篇】说说MVC+EF easyui dataGrid 动态加载分页表格

    首先上javascript的代码 <script type="text/javascript"> $(function () { LoadGrid(); }) //加载 ...

  9. 使用MySQL Proxy解决MySQL主从同步延迟

    MySQL的主从同步机制非常方便的解决了高并发读的应用需求,给Web方面开发带来了极大的便利.但这种方式有个比较大的缺陷在于MySQL的同步机制 是依赖Slave主动向Master发请求来获取数据的, ...

  10. 正则化,数据集扩增,Dropout

    正则化方法:防止过拟合,提高泛化能力 在训练数据不够多时,或者overtraining时,常常会导致overfitting(过拟合).其直观的表现如下图所示,随着训练过程的进行,模型复杂度增加,在tr ...