jquery 对象方法-jQuerydefered 和 Promise 对象方法

一、简介

为了让后端从反弹地狱回到天堂,jQuery还引入了Promise的概念。 Promise 是一种具体的表示,它让代码的异步行为变得更加高贵。 有了它,我们就可以像编写同步代码一样编写异步代码。 jQuery从1.5版本开始就实现了CommonJSPromise/A规范的重量级方案,但并没有严格按照规范来实现,并且存在一些API差异。

好吧,我们来看看它们的特点(本文的例子基于jQuery1.8及以上版本)。

二、举例

以前我们写动漫的时候,通常是这样写的:

$('.animateEle').animate({
    opacity:'.5'
}, 4000,function(){
    $('.animateEle2').animate({
        width:'100px'
    },2000,function(){
        // 这样太伤了
        $('.animateEle3').animate({
            height:'0'
        },2000);
    });
});

如果这样用反弹的话,伤害就太大了。 值得庆幸的是jquery 对象方法,有一些现成的 Promise 解决方案可以优雅地解决这些问题。

我们来看看jQuery提供的解决方案。

var animate1 = function() {
    return $('.animateEle1').animate({opacity:'.5'},4000).promise();
};
var animate2 = function() {
    return $('.animateEle2').animate({width:'100px'},2000).promise();
};
var animate3 = function(){
    return $('.animateEle3').animate({height:'0'},2000).promise();
};
// so easy,有木有,so clear,有木有
$.when(animate1()).then(animate2).then(animate3);

显然,修改后的代码更容易理解和阅读。

不过,内部代码的一些细节并未公开。 如果不小心,很容易出错,无法达到按照我们想要的顺序完成动画的效果。 让我们充分了解 jQuery 提供的 Promise 和 deferred 对象,并看看如何使用它们。

三、Promise和Deffered对象模式

虽然 Promise 对象是延迟对象的特例,但由于 Promise 对象无法修改异步状态,而延迟对象可以。 这在他们的方法设计中很明显。

1.Promise对象方法

对象方法和类方法的区别_jquery 对象方法_对象方法只能通过什么进行调用

一般我们对于DOM、动画、ajax相关的技巧都可以使用Promise方法。 调用 Promise 方法会返回一个 Promise 对象。 Promise方法可以链式调用。

Promise 对象有三种常见的方式:done、fail、then。

不要忘记其他方法。 jQuery 中的套接字方法太多。 在我看来,这是相当冗长的。 与初始的storm方法绑定相同。 Live、delegate、bind最后并不都归为on。 是吗?

代码示例如下:

1. DOM使用Promise方法:

var box=$('#box');
box.promise().done(function(ele){
    console.log(ele);//jQuery box
});

2、Ajax使用Promise方法(默认返回一个Promise对象,所以不需要显式调用Promise方法):

对象方法和类方法的区别_jquery 对象方法_对象方法只能通过什么进行调用

$.post('/',{}).done(function(data){
    console.log('请求成功');
}).fail(function(){
    console.log('请求错误');
});

动画例子已经有了,我就不再重复了。

2. 延迟对象方法

对于延迟对象,即使用 $.Deferred() 和 $.when() 方法创建的对象,有以下常用技巧:

还有承诺、当时和永远的方法。

之所以这样排版,是因为它们是对应的,也就是说:resolve方法会触发done的反弹执行,reject会触发fail的反弹,notify会触发progress的反弹。

直接看代码:

jquery 对象方法_对象方法和类方法的区别_对象方法只能通过什么进行调用

var wait = function(ms) {
    var dtd = $.Deferred();
    setTimeout(dtd.resolve, ms);
    // setTimeout(dtd.reject, ms);
    // setTimeout(dtd.notify, ms);
    return dtd.promise(); //此处也可以直接返回dtd
};
wait(2500).done(function() {
    console.log('haha,师太,你可让老衲久等了');
}).fail(function() {
    console.log('失败了');
}).progress(function(res) {
    console.log('等待中...');
});

我们看到,在里面的代码中,在wait函数中,返回的是一个Promise对象,而不是一个deferred对象。

要知道Promise对象没有resolve、reject、notify等方法,这意味着你无法修改Promise对象的状态,只能在done或fail时进行反弹配置。 因此,如果这样调用wait(2500).resolve(),就会报错,因为wait(2500)返回的是一个Promise对象,并且没有resolve技术。

然而,这样做有一个好处。 我们将延迟对象dtd作为局部变量放在wait函数中,防止全局污染; 等待之外可能发生的状态修改(如果我们确实有这个需求)。

例如:

var wait = function(ms) {
    var dtd = $.Deferred();
    setTimeout(dtd.resolve, ms);
    // setTimeout(dtd.reject, ms);
    // setTimeout(dtd.notify, ms);
    return dtd; //此处也可以直接返回dtd
};
wait(2500).reject().fail(function(){
    console.log('失败了...............');
});

我们在外部修改wait返回的延迟对象的状态jquery 对象方法,这必然会触发对象的失败反弹函数。

对于always方法,从字面意思很容易理解,无论延迟对象被解析还是被拒绝,都会触发这种技术的反弹。

3.其他共性

这里我们讨论then和$.when技巧的使用。 它们也适用于 Promise 对象。

我们看一下最初的动画示例代码,$.when(animate1()).then(animate2).then(animate3),$.when方法接受一个animate1函数的执行结果,即得到一个Promise对象,然后在then中,只接受一个变量名,所以结果是一个匿名函数体,函数返回一个Promise对象。 它正好满足我们接受参数的要求。

如果我们把执行语句改为:$.when(animate1()).then(animate2()).then(animate3()),结果就是三个动画同步执行。 与 $.when(animate1(), animate2(), animate3()) 相同。

既然是这样的要求,完成、失败、进度和那时类似也是一样的。

4.参考文章

因为 jQuery deferred 和 Promise 对象方法使用起来很繁琐,而且套接字太多,所以您可以有多种方法来编写同一件事。 因此,单独的套接字方法可能已过时。 如果您想使用其他方法,请参考官方网站。