JS异步编程-详解Promise对象

概述

Promise对象项有两种可能结果(成功/失败)的任务,拥有多个回调函数,以便出现不同结果时分别触发相应的回调。

var promise = $.get(url);

promise.done(onSuccess);  //get获取成功后,调用onSuccess

promise.fail(onFailure);     //get获取成功后调用onFailure

promise.always(onAlways);//始终都会调用onAlways(恒调)

上例在触发Ajax后再附加回调的好处:封装,如果Ajax调用要实现很多效果(触发动画、插入HTML、锁定/解锁用户输入),仅由发出请求的那部分代码来处理所有这些效果,显得很蠢,不够优雅。因为Promise对象也允许向同一事件绑定任意多的处理器(堆积技术)。


生成Promise对象

Ajax方法($.ajax,$.get,$.post)以及$.when都可以返回Promise对象,同时也可以自己手动生成。举例

var myDeferred = new $.Deferred();

如果正在进行的一次性一步操作的结果可以笼统的分为两种(成功/失败,接受/拒绝),则生成的Deferred对象/Promise对象就能直接的表达这次任务。

$.Deferred()即可生成一个Promise对象,实际上,Deferred就是Promise的超集,仅仅多了一项关键的特性:可以直接触发。就是说Promise对象只允许在后面添加多个调用,能否触发这些调用,我们没有决定权;但是使用resolve(执行)方法和reject(拒绝)方法可以直接触发Deferred对象。resolve触发done回调,reject触发fail回调。如下

myDeferred.resolve();  //使用resolve()方法直接触发Deferred对象的done事件

那么如何手动生成纯的Promise对象呢?其实,对Deferred对象调用promise()即可

var purePromise = myDeferred.promise(); 

purePromis是myDeferred对象的一个没有resolve/reject方法的副本。因此,对同一个Deferred对象生成多个Promise对象是没有意义的,因为只不过是同一个对象;对一个纯Promise对象调用promise()也是没有意义的,因为只不过是一个指向同一个对象的引用。


jQuery中的Promise对象

由上可见,Ajax是演示Promise的绝佳用例:每次对远程服务器的调用都是成功/失败,而我们希望以不同的方式来处理这两种情况。Promise同样适用于本地的一些异步操作,如动画效果:

$('.error').fadeIn(afterErrorShown);

jQuery中任何动画方法都可以接受传入的回调,以便在完成动画时发出通知。对于动画的完成情况,可以生成Promise对象:

var errorPromise = $('.error').fadeIn().promise();

errorPromise.done(afterErrorShown);

(待完善)


向回调传递数据

Promise对象可以向其回调传递额外的信息。执行/拒绝Deferred对象时,提供的任何参数都会转发至相应的回调:

var myDeferred = new $.Deferred();

myDeferred.done(function(school){console.log('I love ',school);});

myDeferred.resolve('ZJU');  输出 I love ZJU

(待完善)


进度通知

Promise对象是你希望任务结束时发生的一些事,但你应该知道过程和结果一样重要。jQuery1.7中为Promise对象新添了一种可以调用无数次的回调:progress(进度)。

(待)


TIPS:本文只是个人对过去的总结,不保证简洁性、系统性、易懂性。如需交流:zhejiangdaxue2011(微信号)

你可能感兴趣的:(JS异步编程-详解Promise对象)