Javascript基础之Promise

各位小伙伴,又见面啦 ! 今天给大家讲讲promise吧

众所周知,回调函数噩梦(恐怖回调),也被称为恶魔金字塔,指如ajax依赖调用时,回调函数会层层嵌套,而这种层层嵌套的写法,往往会让人难以理解,所以称之为噩梦。

例如:服务器中有3个txt文件,我们需要在html上,通过js中的异步的ajax,分别获取这3个文件的内容,假设这3个文件分别存储的数据为1、2、3,那么我希望在js中,能够求出1+2+3,把6输出。

var str = "";
$.ajax({
   type: "get",
   url: "../data/1.txt",
   success: function (msg1) {
        str += msg1;
        setTimeout(function () {
             $.ajax({
             type: "get",
             url: "../data/2.txt",
             success: function (msg2) {
                   str += msg2;
                   $.ajax({
                       type: "get",
                       url: "../data/3.txt",
                       success: function (msg3) {
                             str += msg3;
                             console.log(str);
                       }
                    })
                 }
             })
         }, 10)

   }
})

看到以上这个代码是不是头都大了, Promise就是解决这种回调函数噩梦的方案之一(Promise 是异步编程的一种解决方案),所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。

Promise对象代表一个异步操作,有三种状态

              pending  (进行中)

              Resolved(已完成,又称Fulfilled)

              Rejected(已失败)

注:可以把Promise看成是状态机,当该Promise对象创建出来之后,其状态就是进行中,然后通过程序来控制到底是执行已完成,还是执行已失败。因为Promise处理的是异步任务,所以我们还得对Promise做监听,当Promise的状态发生变化时,我们要执行相应的函数。

一、 Promise的特点

        1. 对象的状态不受外界影响 => 想要改变状态 需要借助 resolve,rejected 方法

        2. Promise对象一经改变,不能再次改变

二、Promise的优缺点

       优点: 有了Promise对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数

       缺点: 

               1. 无法取消Promise,一旦新建它就会立即执行,无法中途取消。

               2. 如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。(直接报错)

               3. 当处于pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)

三、实例方法

       then(callback1,callback2)

             callback1 当promise实例的状态 由进行中(pending)改为已成功(fullilled)时执行回调函数

             callback2 当promise实例的状态 由进行中(pending)改为已失败(rejected)时执行回调函数,也可以接收代码执行过程中的语法错误/手动抛错throw

new Promise(function (resolve, reject) {
    // 模拟异步操作
    setTimeout(function () {
        var num = parseInt(Math.random() * 10);
        if (num % 2 == 0) {
           resolve("我是成功的num" + num);
        } else {
           reject("我是失败的num" + num);
        }
    })
}).then(function (result) {
   // 成功时执行
   console.log(result);
}, function (err) {
   // 失败时执行
   console.log(err);
})

      catch()

            该方法是.then(null, rejection)或.then(undefined, rejection)的别名,用于指定发生错误时的回调函数。

Tips:  Promise 对象的错误具有“冒泡”性质,会一直向后传递,直到被捕获为止。也就是说,错误总是会被下一个catch语句捕获。

new Promise(function (resolve, reject) {
     // 模拟异步操作
     setTimeout(function () {
         var num = parseInt(Math.random() * 10);
         if (num % 2 == 0) {
             resolve("我是成功的num" + num);
         } else {
             reject("我是失败的num" + num);
         }
     })
}).then(function (result) {
   // 成功时执行
   console.log(result);
}).catch(err => {
   // 失败时执行
   console.log(err);
})

           finally()     不管成功还是失败都会执行

new Promise(function (resolve, reject) {
     // 模拟异步操作
     setTimeout(function () {
         var num = parseInt(Math.random() * 10);
         if (num % 2 == 0) {
             resolve("我是成功的num" + num);
         } else {
             reject("我是失败的num" + num);
         }
     })
}).then(function (result) {
   // 成功时执行
   console.log(result);
}).catch(err => {
   // 失败时执行
   console.log(err);
}).finally(()=>{
   console.log("到达终点")
})

四、构造函数的方法

            Promise.all()      用于将多个 Promise 实例,包装成一个新的 Promise 实例      

Promise.all([p1, p2, p3])  => p

           p的状态由p1、p2、p3决定,分成两种情况:

                      a. 只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。

                      b. 只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。

// 只要p1,p2,p3中有一个状态为rejected,p的状态则为rejected,否则为fulfilled
var p = Promise.all([p1, p2, p3]);
p.then(function (list) {
    console.log(list);
}).catch(err => {
    console.log(err);
})

           Promise.allSettled()   用于将多个 Promise 实例,包装成一个新的 Promise 实例

                      只有等到所有这些参数实例都返回结果,不管是fulfilled还是rejected,包装实例才会结束

Tips:  一旦结束,状态总是fulfilled,不会变成rejected

           Promise.race()    用于将多个 Promise 实例,包装成一个新的 Promise 实例

                    只要p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数

          Promise.resolve()   快速生成一个fulilled状态 Promise实例,并将传入的参数作为实例的返回值     

// 参数是一个实例
console.log(Promise.resolve(1));

// 参数是一个   thenable对象 
var p = Promise.resolve({
    then: function (resolve, reject) {
        var num = Math.round(Math.random() * 10);
        // console.log(num);
        if (num % 2 == 1) {
            resolve("我是失败的" + num);
        } else {
            reject("我是失败的" + num);
        }
   }
})
p.then(result => {
    console.log(result);
).catch(err => {
    console.log(err);
})

          Promise.reject()    快速生成一个rejected状态 Promise实例,并将传入的参数作为实例的返回值

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值