【JS】JavaScript异步系列(2)——jQuery的deferred对象实现Promise接口

本文介绍了JavaScript中Promise的概念及其在解决异步操作中回调地狱问题的应用,并详细解析了jQuery的Deferred对象实现方式,包括基本使用方法、状态管理及$.when()的用法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

说明

该博客转载自以下链接的博客,原博客链接为:
http://imweb.io/topic/5632180ef33f23d4366f7981

Promise是什么?

我们知道JavaScript是单线程,如果遇到某些耗时很长的javascript操作,那么其他的操作就必须等待。,通常的解决方法是将那些排在后面的操作,写成“回调函数”(callback)的形式。事先规定当他们结束运行后,应该调用那些函数。但是这样有一些显著缺点:

  • 回调函数往往写成函数参数的形式,导致函数的输入和输出非常混乱,整个程序的可阅读性差;
  • 回调函数往往只能指定一个,如果有多个操作,就需要改写回调函数。
  • 整个程序的运行流程被打乱,除错和调试的难度都相应增加。 Promises就是为了解决这些问题而提出的,它的主要目的就是取代回调函数,成为非同步操作的解决方案。它的核心思想就是让非同步操作返回一个对象,其他操作都针对这个对象来完成。

jQuery中的promise的实现——deferred对象

deferred对象是jQuery的回调函数解决方案,它解决了如何处理耗时操作的问题,对那些操作提供了更好的控制,以及统一的编程接口。 下面来看下他的具体的使用方法:

ajax操作的写法:

先看下传统写法:

  $.ajax({
    url: "test.html",
    success: function(){
      console.log(“成功”);
    },
    error:function(){
      console.log(“失败”);
    }
  });

其中success 和 error方法分别指定操作成功和失败的回调函数。

现在新的ajax操作的写法是这样的:

$.ajax(test.html")
  .done(function(){
      console.log(“成功”); 
})
  .fail(function(){
});

done()相当于success方法,fail()相当于error方法。

注意,如果使用的是低于1.5.0版本的jQuery,返回的是XHR对象,没法进行链式操作;如果高于1.5.0版本,返回的是deferred对象,可以进行链式操作。

新的ajax操作也可以这样写:

$.ajax("test.html").then(function(){
        console.log(“成功”);
        }, function(){
        console.log(“失败”);
        });

这里介绍下deferred.then() 方法,有时为了省事,可以把done()和fail()合在一起写,这就是then()方法。如果then()有两个参数,那么第一个参数是done()方法的回调函数,第二个参数是fail()方法的回调方法。如果then()只有一个参数,那么等同于done()。

deferred对象的方法

$.deferred()方法

$.deferred()方法,作用是生成一个deferred对象,它允许你自由添加多个回调函数。

 var def = $.Deferred();
    def.done(function(){
        console.log(“成功”);
    }).fail(function(){
         console.log(“失败”);
    }).done(function(){
        console.log(“再一次成功”);
    })

回调函数可以添加任意多个,它们按照添加顺序执行。 其中,done() 和 fail()这两个方法都用来绑定回调函数。done()指定操作成功后的回调函数,fail()指定失败后的回调函数。

state方法

state方法用来返回deferred对象目前的状态,deferred对象有三种状态:操作还没有完成、操作成功、操作失败,对应state方法的返回值为:pending、resolved、rejected

var deferred = $.Deferred();
 alert(deferred.state());  // "pending"
 deferred.resolve();
 alert(deferred.state());  // "resolved"

resolve() 和 reject()

前面说过deferred对象有三种执行状态—-未完成,已完成和已失败。如果执行状态是”已完成”(resolved),deferred对象立刻调用done()方法指定的回调函数;如果执行状态是”已失败”,调用fail()方法指定的回调函数;如果执行状态是”未完成”,则继续等待,或者调用progress()方法指定的回调函数

var def = $.Deferred();
        def.done(function() {
           alert(value);
    }).fail(function(){
        alert("hello");
    })
    def.resolve("hello world");

$.when()方法

$.when()接受多个deferred对象作为参数,当它们全部运行成功后,才调用resolved状态的回调函数,但只要其中有一个失败,就调用rejected状态的回调函数。它允许你为多个事件指定一个回调函数

 $.when($.ajax("test1.html"), $.ajax("test2.html"))
  .done(function(){ alert("成功"); })
  .fail(function(){ alert("失败"); });

上面的代码先执行两个操作$.ajax("test1.html")$.ajax("test2.html"),如果都成功了,就运行done()指定的回调函数;如果有一个失败或都失败了,就执行fail()指定的回调函数。

注意如果when()它的参数返回的不是一个Deferred或Promise对象,那么when方法的回调函数将立即运行。

普通函数如何使用回调函数呢? 例如有这样的函数

var wait = function(){
   setTimeout(function(){
   alert("执行完毕!");
   },3000);
 };
 wait();

现在为他指定回调函数

var dtd = $.Deferred();     // 新建一个deferred对象
var wait = function(dtd){
    setTimeout( function(){
      alert("执行完毕!");
      dtd.resolve();    // 改变deferred对象的执行状态
    },3000);
    return dtd;
  };

  $.when(wait(dtd))
  .done(function(){ 
      alert("哈哈,成功了!");
   })
  .fail(function(){ 
      alert("出错啦!");
   });

这样wait函数的返回值就是Deferred对象,when()函数能生效,wait()函数运行完,就会自动运行done()方法指定的回调函数。

always()

这个方法也是用来指定回调函数的,它的作用是,不管调用的是deferred.resolve()还是deferred.reject(),最后总是执行。

 $.ajax( "test.html" )
  .always( function() { alert("已执行!");} );
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值