jQuery中deferred对象进行回调处理

举报
空城机 发表于 2021/11/30 18:08:46 2021/11/30
【摘要】 在jQuery当中,存在一个deferred延时对象,deferred对象就是jQuery的回调函数解决方案

deferred对象

jQuery当中,存在一个deferred延时对象,deferred对象就是jQuery的回调函数解决方案

在当前ES6中的Promise出来后,jQuerydeferred的使用就少了很多,毕竟有了更好的解决方案。

不过本文主要讲述的还是deferred。 在jquery较高的版本中,都是已经支持deferred对象了。

开发网站的过程中,我们经常遇到某些耗时很长的javascript操作。其中,既有异步的操作(比如ajax读取服务器数据),也有同步的操作(比如遍历一个大型数组),它们都不是立即能得到结果的。
通常的做法是,为它们指定回调函数(callback)。即事先规定,一旦它们运行结束,应该调用哪些函数。
但是,在回调函数方面,jQuery的功能非常弱。

在使用jQuery的ajax时,可以直接在后面调用。

例子:

function getAjax() {
    $.get("http://localhost:3001/goodsList")
    .done(function(data){ console.log(data); })
    .fail(function(){ console.log("出错啦!"); });
}

80901.gif

从这个例子中就可以看到,jQueryAjax请求获取的数据可以通过链式的写法来避免造成回调地狱。


deferred实例

当然这里是直接使用$.ajax,所以对于deferred的使用看起来并不明显,那么接下来使用setTimeout的一个例子来实际写一下deferred的延迟用法吧。

在下面两个方法当中,执行random方法之后,需要知道setTime方法中的num改变,才能继续走下去,因为内部存在setTimeout,所以并不确定num改变的时间:

function random() {
    let randomTime = Math.random()*1000;
    setTime(randomTime)
}
function setTime(randomTime) {
    let num = 0;
    setTimeout(()=>{
        num = randomTime;
    }, randomTime)
}

同步思维

setTimeout的存在,导致异步,如果按照同步的思路会是以下写法:

function random() {
    let randomTime = Math.random()*1000;
    let res = setTime(randomTime)
    change(res);
}
function setTime(randomTime) {
    let num = 0;
    setTimeout(()=>{
        num = randomTime;
        return num;
    }, randomTime)
}
function change(num) {
    console.log(`num数值改变,当前为:${num}`);
}

但是这样肯定会出错,结局如下:

80901.gif

回调解决

如果是使用回调方法,可以如下编写:

function random() {
    let randomTime = Math.random()*1000;
    setTime(randomTime, change)
}
function setTime(randomTime,callback) {
    let num = 0;
    setTimeout(()=>{
        num = randomTime;
        callback(num);
    }, randomTime)
}
function change(num) {
    console.log(`num数值改变,当前为:${num}`);
}

效果:

80901.gif

但是如果更加复杂的情况,就很容易写成回调地狱,一层套一层的情况。

deferred解决方式

function random() {
    let randomTime = Math.random()*1000;
    let res = setTime(randomTime);
    res.done((result)=>{
        // 返回的result并不是结果,而是方法
        change(result());
    }).then((val)=>{
        // 可以使用.then继续走下去
        console.log(val());
    })
}
function setTime(randomTime) {
    let num = 0;
    let dfr = $.Deferred(); // 定义Deferred
    setTimeout(()=>{
        num = randomTime;
        // 改变deferred对象的执行状态,这里可以返回num作为resolve的结果
        dfr.resolve(()=>{ 
            return num;
        });
    }, randomTime)
    return dfr.promise();
}
function change(num) {
    console.log(`num数值改变,当前为:${num}`);
}

当前效果,已经达到和回调相同的方式,并且可以通过.then方法持续走下去,避免产生多余的回调:

80901.gif


当然其实jQuery中的deferred还有更多的衍生方法,这里推荐阮一峰老师的教程。

参考文章: jQuery的deferred对象详解

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

举报
请填写举报理由
0/200