ES6中的promise

在阮一峰的ES6中是这样解释promise的 Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。

一.回调函数

一个回调函数,也被称为高阶函数;也就是把一个B函数当成一个参数传递给另一个A函数。B函数需要在A函数中进行调用,这个B函数就叫回调函数。A函数执行完成之后B函数才会执行。这个过程是回调。
注意:回调函数不是立即就执行。它是在另一个函数执行完成之后被调用,即在包含的函数体中指定的地方调用。

  //第一种情况:
  $("button").on("click", () => {
            alert("hello")
        })
   /*
      在jQuery这个点击事件的方法中,我们传递了一个函数作为参数传递给了click
   */
 
 //第二种情况:
 [1,2,3].forEach((item,index,obj)=>{
              console.log(item)
        })
    /*
      同理,在ES5新增的数组方法中,都是接收一个函数作为参数
    */
 //第三种情况:
    function A(callback) {
        callback();
        console.log("我是主函数")
    }

    function B() {
        setTimeout(() => {
            console.log("我是回调函数")
        }, 2000)
    }
    A(B)
    /*
       按顺序先执行回调函数,但输出结果却是后输出回调函数内容,A函数不用等回调函数执行完再执行后续的语句,可以执行自己的代码,等回调函数准备好,再执行回调函数。所谓异步加载也不过如此。因此可以证明异步与回调并没有直接的联系,回调只是异步的一种实现方式
    */

 function syncfn(callback) {
            callback()
        }

        syncfn(function() {
            alert("我是同步函数里的函调函数")
        })

        function async(callback) {
            setTimeout(function() {
                callback()
            }, 1000)
        }

        async(function() {
            alert("我是异步函数里的回调函数")
        })
 /*
   这个例子说明异步和回调函数没有直接的联系,回调只是异步的一种实现方式
 */

二 promise

1.为什么需要promise 比如我们再等待一个请求结果的时候,需要上一条ajax请求的结果,那我们就会产生回调套回调的情况:

  //这里我们使用定时器来,模拟一下,
  setTimeout(function() {
          console.log(1)
          setTimeout(function() {
              console.log(2)
              setTimeout(function() {
                  console.log(3)
              }, 1000)
          }, 1000)
      }, 1000)
      

//我们这里写一段伪代码,在实际场景下我们很容易看到这种情况,如果依赖的层级关系更加多的话,就很容易造成回调地狱
   $.ajax({
          type: "method",
          url: "url",
          data: "data",
          dataType: "dataType",
          success: function (response) {
               $.ajax({
                   type: "method",
                   url: "url",
                   data: "data",
                   dataType: "dataType",
                   success: function (response) {
                        $.ajax({
                            type: "method",
                            url: "url",
                            data: "data",
                            dataType: "dataType",
                            success: function (response) {
                                
                            }
                        });
                   }
               });
          }
      });

这时,我们可能会希望:

让代码变得更具有可读性和可维护性,减轻一层层套用数据和请求的现象;
将请求和数据处理明确的区分开;
这样我们的promise就登场了,promise中的then方法,可以解决刚刚出现的恐怖的回调函数问题,让代码更加优雅;

2.promise的API

构造函数属性:
1)本身就是一个构造函数,具有constructor属性,并且指针指向它的构造函数promise
在这里插入图片描述
2) Promise 新建后就会立即执行。

let promise = new Promise(function(resolve, reject) {
    console.log('Promise');
    resolve();
  });
  
  promise.then(function() {
    console.log('resolved.');
  });
  
  console.log('Hi!');

实例方法
1).promise.then() 成功的时候调用
2).promise.catch() 失败的时候调用

promise.then成功和失败时都可以使用,并且then方法的执行结果也会返回一个Promise对象。

promise.then()的第二个参数和promise.catch()捕获错误的区别:

1.promise.then()的第二个参数可以捕获到
在这里插入图片描述
在这里插入图片描述
如果想要捕获到图1中的错误,那么就需要使用try{}catch(err){}的方法进行捕获;

2.promise.catch()的是可以捕获到.then()方法中的错误信息的。

静态方法:
Promise.all()方法用于将多个 Promise 实例,包装成一个新的 Promise 实例,当所有的promise对象有返回值的时候,同时返回
Promise.race()方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例,返回的是第一个改变promise实例。

Promise.resolve() 有时需要将现有对象转为 Promise 对象,Promise.resolve()方法就起到这个作用。

Promise.resolve()等价于下面的写法。

  Promise.resolve('foo')
  // 等价于
  new Promise(resolve => resolve('foo'))

Promise.reject() Promise.reject(reason)方法也会返回一个新的 Promise 实例,该实例的状态为rejected。

  const p = Promise.reject('出错了');
  // 等同于
  const p = new Promise((resolve, reject) => reject('出错了'))


promise 对象的特点:

1)对象的状态不受外界影响,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败),只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是Promise这个名字的由来,它的英语意思就是“承诺”,表示其他手段无法改变
2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。如果改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。

3:promise的状态:

 const p1 = new Promise(function(resolve, reject) {});  // 进行中
      const p2 = new Promise(function(resolve, reject) {
         resolve(p1);
     })
     p2.then(res => {
         console.log("p2")
     })
     因为p1一直没有执行所以,p2没有返回值

  let p1 = new Promise((resolve, reject) => {
         if (false) {
             resolve("成功")
         } else {
             reject("失败")
         }
     })
         let p2 = new Promise(function(resolve, reject) {
             resolve(p1)
         })

         p2.then(res => {
             console.log(res)
         }).catch(err => {
             console.log(err)
         })

         p1的状态决定着p2的状态

三 promise的使用

1:promise的执行顺序

var p = new Promise((resolve, reject) => {
    //做一些异步操作
    setTimeout(() => {
        console.log('执行完成');
        resolve('我的数据');
    }, 0);
    console.log("我先执行")
});
//先输出:我先执行
//1秒之后输出:执行完成

我们这里简单可以理解:
异步任务:指不进入主线程,而是进入“任务队列的任务”,只有等主线程任务执行完毕,“任务队列”开始通知主线程,请求执行任务,该任务才会进入主线程执行。
同步任务:指在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务;

promise的链式操作和数据传递:

       function fn(num) {
          return new Promise((resolve, reject) => {
              setTimeout(function() {
                  resolve(num)
              }, 1000)
          })
      }

      fn(1).then(res => {
          console.log(res)
          return fn(++res)
      }).then(res => {
          console.log(res)
          return fn(++res)
      }).then(res => {
          console.log(res)
      })

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值