理解jQuery中的Promise

来源:互联网 发布:apache kylin使用教程 编辑:程序博客网 时间:2024/05/29 03:58

首先回顾一下jQuery的deferred对象:
jQuery的deferred对象

关于Promise的进化史

在jQuery1.4中,还没有promise这个概念,写一个ajax,就得写回调函数,就像这样:

$.get('/myData', {    success: onSuccess,    failure: onFailure,    always: onAlways})

到了jQuery1.5+之后,有了promise,就可以给ajax 的get返回的就是一个promise对象(我这样理解不知道对不对)
然后代码的形式就变成了这样:

var promise = $.get('/myData');promise.done(onSuccess);promise.fail(onFailure);promise.always(onAlways);

这样的好处是Promise对象和EventEmitter对象一样,可以向同一事件绑定任意多的处理器。

promise就是deferred

或者说是用deferred就可以生成一个promise对象

var prompt = new $.Deferred();$('#playGame').focus().on('keypress', function(e) {    var Y = 121,        N = 110;    if (e.keyCode === Y) {        prompt.resolve();    } else if (e.keyCode === N) {        prompt.reject();    } else {        return false; // they must choose!    }});prompt.done(function() {    console.log('Starting game...');});prompt.fail(function() {    console.log('No game today.');});prompt.always(function() {    console.log('A choice was made');});

输入y就会打印
这里写图片描述
输入n就会打印
这里写图片描述
即,每次调用promtDeferred对象,都会先运行一下always(),再运行done或者fail(调用promt.resolve()就是done,reject就是fail)
同时测试结果显示表明,调用了一次之后就不管用了。也就是说Promise对象只能执行或拒绝一次,之后就失效了。期间Promise对象会一直保持挂起状态。
这里我们可以调用promt.state()方法,确实是“pending”
这里我打印一下promt对象的属性和方法,就可以看到promise的方法有always,done,fail,notify…..
这里写图片描述

生成一个纯promise对象

上面的图,我们可以看到promt有一个promise()方法,没错,就是调用这个方法来生成纯promise对象。
这里写图片描述
promise对象和Deferred对象的区别是,没有resolve和reject方法。promise的promise也是指向自己。

因此可以考虑这是一个封装:每个deferred对象都含有一个promise对象,每个promise对象都代表着一个deferred对象。有了deferred对象,就可以控制其状态,有了promise对象就可以读取其状态。

jQuery中的Promise对象

还是参见上面的图,很多方法都没有介绍
首先,说明的是在jQuery中,不仅只有Ajax函数(.ajax,.get, .post)可以返回Promise对象,动画函数也可以返回Promise对象。

notify和progress

Promise对象接受3种回调方式:done、fail和progress。
- 执行Promise对象时,运行的是done回调;
- 拒绝Promise对象时,运行的是fail回调;
- 对于挂起状态的Deferred对象调用notify,运行的是progress回调;

when

when相当于Promise执行情况的逻辑与运算符(AND)。一旦给定的所有Promise均已执行,就立即执行when产生的Promise对象;
或者,一旦给定的任意一个Promise被拒绝,就立即拒绝when产生的Promise。

pipe

pipe是jquery1.6+提供的方法。
pipe是promise上的方法,pipe对象也是promise对象。
这里写图片描述
初始Promise对象的行为一直级联到管道末尾的promise对象。

Promise对象的使用

用Promise对象代替回调函数

deferreCallback = function(deferred) {    return function(err) {        deferred.reject(err)    } else {        deferred.resolve(Array.prototype.slice.call(arguments, 1));    }}var fileReading = new $.Deferred();fs.readFile(filename, 'utf8', deferreCallback(fileReading));

文件读取是一个耗时的工作,我们将Priomise对象代替回调函数,当文件读取成功就执行deferred.resolve,失败就执行deferred.reject。

原创粉丝点击