jQuery的Promise 这里介绍的很详细

原文电梯:https://www.cnblogs.com/yelongsan/p/7644239.html

先前了解了ES6的Promise对象,来看看jQuery中的Promise,也就是jQuery的Deferred对象。

打开浏览器的控制台先。

<script>
    var defer = $.Deferred();
    console.log(defer);
</script>

运行代码

运行结果:

和ES6的Promise对象长的有点像,jQuery的Deferred对象也有resolve、reject、then方法,还有done、fail、always......方法。jQuery就是用这个Deferred对象来注册异步操作的回调函数,修改并传递异步操作的状态。

玩玩Deferred:

<script>
    function runAsync(){
        var defer = $.Deferred();
        //做一些异步操作
        setTimeout(function(){
            console.log(‘执行完成‘);
            defer.resolve(‘异步请求成功之后返回的数据‘);
        }, 1000);
        return defer;
    }
    runAsync().then(function(data){
        console.log(data)
    });
</script>

运行代码

运行之后,Deferred对象的实例defer通过resolve方法把参数 “异步请求成功之后返回的数据” 传回到then方法中进行接收,,打印。

和ES6的Promise相似,但是有一点点区别,再看下Promise:

<script>
    function runAsync(){
        var p = new Promise(function(resolve, reject){

            setTimeout(function(){
                console.log(‘执行完成‘);
                resolve(‘异步请求成功之后返回的数据‘);
            }, 1000);
        });
        return p;
    }

    runAsync().then(function(data){
        console.log(data);
    });
</script>

运行代码

我们发现:

1、创建Deferred对象的时候没有传参;而创建Promise对象的时候,传了参数(传了一个匿名函数,函数也有两个参数:resolve、reject);

2、Deferred对象直接调用了resolve方法;而Promise对象则是在内部调用的resolve方法;

说明:Deferred对象本身就有resolve方法,而Promise对象是在构造器中通过执行resolve方法,给Promise对象赋上了执行结果的状态。

这样就有一个弊端:因为Deferred对象自带resolve方法,拿到Deferred对象之后,就可以随时调用resolve方法,其状态可以进行手动干预了

<script>
    function runAsync(){
        var defer = $.Deferred();
        //做一些异步操作
        setTimeout(function(){
            console.log(‘执行完成‘);
            defer.resolve(‘异步请求成功之后返回的数据‘);
        }, 1000);
        return defer;
    }   var der = runAsync();
   der.then(function(data){
        console.log(data)   });
   der.resolve(‘在外部结束‘); 
</script>

运行代码

这样的话就直接在外部直接给Deferred设置了状态,打印“在外部结束”,1s后打印“执行完成”,不会打印“异步请求成功之后返回的数据”了。

显然,这不好。我发个异步请求,还没收到数据就让人在外部给我结束了。。。。。。。

当然这个坑jQuery肯定会填的,在Deferred对象上有一个promise方法,是一个受限的Deferred对象

<script>
    function runAsync(){
        var def = $.Deferred();
        //做一些异步操作
        setTimeout(function(){
            console.log(‘执行完成‘);
            def.resolve(‘请求成功之后返回的数据‘);
        }, 2000);
        return def.promise(); //就在这里调用
    }
</script>

所谓受限的Deferred对象,就是没有resolve和reject方法的Deferred对象。这样就无法在外边改变Deferred对象的状态了。

Deferred对象的then方法和done、fail语法糖

我们知道,在ES6的Promise规范中,then方法接受两个参数,分别是执行完成和执行失败的回调,而jquery中进行了增强,还可以接受第三个参数,就是在pending状态时的回调,如下:

deferred.then( doneFilter [, failFilter ] [, progressFilter ] )

then方法

<script>
    function runAsync(){
        var def = $.Deferred();
        //做一些异步操作
        setTimeout(function(){
              var num = Math.ceil(Math.random()*10); //生成1-10的随机数
               if(num<=5){
                   def.resolve(num);
               }
               else{
                   def.reject(‘数字太大了‘);
               }
        }, 2000);
        return def.promise(); //就在这里调用
    }

    runAsync().then(function(d){
        console.log("resolve");
        console.log(d);
    },function(d){
        console.log("reject");
        console.log(d);
    })

</script>

运行代码

Deferred对象的then方法也是可以进行链式操作的。

done,fail语法糖,分别用来指定执行完成和执行失败的回调,与这段代码是等价的:

<script>
    function runAsync(){
        var def = $.Deferred();
        //做一些异步操作
        setTimeout(function(){
              var num = Math.ceil(Math.random()*10); //生成1-10的随机数
               if(num<=5){
                   def.resolve(num);
               }
               else{
                   def.reject(‘数字太大了‘);
               }
        }, 2000);
        return def.promise(); //就在这里调用
    }

    runAsync().done(function(d){
        console.log("resolve");
        console.log(d);
    }).fail(function(d){
        console.log("reject");
        console.log(d);
    })

</script>

运行代码

always的用法

jquery的Deferred对象上还有一个always方法,不论执行完成还是执行失败,always都会执行,有点类似ajax中的complete。

$.when的用法

jquery中,还有一个$.when方法来实现Promise,与ES6中的all方法功能一样,并行执行异步操作,在所有的异步操作执行完后才执行回调函数。不过$.when并没有定义在$.Deferred中,看名字就知道,$.when,它是一个单独的方法。与ES6的all的参数稍有区别,它接受的并不是数组,而是多个Deferred对象,如下:

<script>
 function runAsync(){
        var def = $.Deferred();
        //做一些异步操作
        setTimeout(function(){
              var num = Math.ceil(Math.random()*10); //生成1-10的随机数
              def.resolve(num);
        }, 2000);
        return def.promise(); //就在这里调用
    }
    $.when(runAsync(), runAsync(), runAsync()) .then(function(data1, data2, data3){     console.log(‘全部执行完成‘);     console.log(data1, data2, data3);  });
</script>

运行代码

jquery中没有像ES6中的race方法吗?就是以跑的快的为准的那个方法。对的,jquery中没有。

以上就是jquery中Deferred对象的常用方法了。

在上一篇和本篇当中,都是用一次性定时器来代替了异步请求进行数据处理。为什么没用ajax呢,不是因为麻烦,在这里要说一下ajax和Deferred的联系:

jquery的ajax返回一个受限的Deferred对象,也就是没有resolve方法和reject方法,不能从外部改变状态,既然是Deferred对象,那么我们上面讲到的所有特性,ajax也都是可以用的。比如链式调用,连续发送多个请求:

<script>
req1 = function(){
    return $.ajax(/* **** */);
}
req2 = function(){
    return $.ajax(/* **** */);
}
req3 = function(){
  return $.ajax(/* **** */);
}
req1().then(req2).then(req3).done(function(){ console.log(‘请求发送完毕‘); });
</script>

success、error与complete

这三个方法是我们常用的ajax语法糖。

$.ajax(/*...*/)
.success(function(){/*...*/})
.error(function(){/*...*/})
.complete(function(){/*...*/})

有时候比较喜欢在内部作为属性来处理。

分别表示ajax请求成功、失败、结束的回调。这三个方法与Deferred又是什么关系呢?其实就是语法糖,success对应done,error对应fail,complete对应always,就这样,只是为了与ajax的参数名字上保持一致而已。

总结:

$.Deferred实现了Promise规范,then、done、fail、always是Deferred对象的方法。$.when是一个全局的方法,用来并行运行多个异步任务,与ES6的all是一个功能。ajax返回一个受限的Deferred对象,success、error、complete是ajax提供的语法糖,功能与Deferred对象的done、fail、always一致。

原文地址:https://www.cnblogs.com/liujinyu/p/9480479.html

时间: 2024-10-12 02:16:15

jQuery的Promise 这里介绍的很详细的相关文章

很详细、很移动的Linux makefile教程:介绍,总述,书写规则,书写命令,使用变量,使用条件推断,使用函数,Make 的运行,隐含规则 使用make更新函数库文件 后序

很详细.很移动的Linux makefile 教程 内容如下: Makefile 介绍 Makefile 总述 书写规则 书写命令 使用变量 使用条件推断 使用函数 make 的运行 隐含规则 使用make更新函数库文件 后序 近期在学习Linux下的C编程,买了一本叫<Linux环境下的C编程指南>读到makefile就越看越迷糊,可能是我的理解能不行. 于是google到了以下这篇文章.通俗易懂.然后把它贴出来,方便学习. 后记,看完发现这篇文章和<Linux环境下的C编程指南>

转: angularjs学习总结(~~很详细的教程)

1 前言 前端技术的发展是如此之快,各种优秀技术.优秀框架的出现简直让人目不暇接,紧跟时代潮流,学习掌握新知识自然是不敢怠慢. AngularJS是google在维护,其在国外已经十分火热,可是国内的使用情况却有不小的差距,参考文献/网络文章也很匮乏.这里便将我学习AngularJS写成文档,一方面作为自己学习路程上的记录,另一方面也给有兴趣的同学一些参考. 首先我自己也是一名学习者,会以学习者的角度来整理我的行文思路,这里可能只是些探索,有理解或是技术上的错误还请大家指出:其次我特别喜欢编写小

jQuery UI Datepicker使用介绍

本博客使用Markdown编辑器编写 在企业级web开发过程中,日历控件和图表控件是使用最多的2中第三方组件.jQuery UI带的Datepicker,日历控件能满足大多数场景开发需要.本文就主要讨论jQuery UI Datepicker的使用,和中文本地化配置. 1.jQuery UI介绍 jQuery UI是一套基于jQuery控件和动画效果Javascript类库.可以用来构建交互式的互联网应用程序.最新版本1.10.4.基于jQuery 1.6+jQuery UI官方网站 2.jQu

jquery jtemplates.js模板渲染引擎的详细用法第一篇

jquery jtemplates.js模板渲染引擎的详细用法第一篇 Author:ching Date:2016-06-29 jTemplates是一个基于JQuery的模板引擎插件,功能强大,有了他你就再不用为使用JS绑定数据时发愁了.后端语言使用php,asp.net,jsp等都不是问题,使用模板渲染可以很大程度上提高程序性能,使用异步获取数据,不用整个页面都回发,好处当然不仅仅是这些. 下载jtemplates,官网的文档写得非常的详细 打开官网:http://jtemplates.tp

[转]Java多线程学习(总结很详细!!!)

Java多线程学习(总结很详细!!!) 此文只能说是java多线程的一个入门,其实Java里头线程完全可以写一本书了,但是如果最基本的你都学掌握好,又怎么能更上一个台阶呢? 本文主要讲java中多线程的使用方法.线程同步.线程数据传递.线程状态及相应的线程函数用法.概述等.首先让我们来了解下在操作系统中进程和线程的区别: 进程:每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,一个进程包含1--n个线程.(进程是资源分配的最小单位) 线程:同一类线程共享代码和数据空间,

Intel 编译器 内存安全检查 真心的很详细 转

Managing Memory Errors with Intel? Parallel Inspector XE ___________________________________________________________________ Intel? Academic Community Disclaimer The information contained in this document is provided for informational purposes only a

Intel 编译器 静态安全检查 真心的很详细 转

Static Security Analysis with Intel? Parallel Inspector XE ___________________________________________________________________ Intel? Academic Community Disclaimer The information contained in this document is provided for informational purposes only

Intel 编译器 线程安全检查 真心的很详细 转

Managing Threading Errors with Intel? Parallel Inspector XE ___________________________________________________________________ Intel? Academic Community Disclaimer The information contained in this document is provided for informational purposes onl

讲的很详细的一篇关于object equals() &amp; hashCode() 的文章

转: 讲的很详细的一篇关于object equals() & hashCode() 的文章 哈希表这个数据结构想必大多数人都不陌生,而且在很多地方都会利用到hash表来提高查找效率.在Java的Object类中有一个方法: 1 public native int hashCode(); 根据这个方法的声明可知,该方法返回一个int类型的数值,并且是本地方法,因此在Object类中并没有给出具体的实现. 为何Object类需要这样一个方法?它有什么作用呢?今天我们就来具体探讨一下hashCode方