剖析ES6的Promise对象

Promise出现的原因

传统解决异步操作的时候是采用使用回调函数的方式,并且当存在多个异步操作需要处理时,需要多次嵌套回调就会产生callback hell,且代码的可读性不高。Promise能够很好的解决这些问题。

Promise对象的状态

Promise 对象有三种状态:

  •   Fulfilled 可以理解为成功的状态
  •   Rejected 可以理解为失败的状态
  •   Pending 既不是 Fulfilld 也不是 Rejected 的状态,可以理解为 Promise 对象实例创建时候的初始状态

使用resolve将Promise的状态转变为成功状态;使用reject将Promise的状态转变为失败状态。

Promise简单使用

let ajax = fucntioon (flg) {
  return new Promise(function (resolve,reject) {
    if (flg) {
      resolve('Hello');   // 将Promise的状态转变为成功状态
    } else {
      reject('Error');      // 将Promise的状态转变为失败状态
    }
  })
}

// 执行函数返回一个Promise对象
//当对象状态转变为成功状态的时候调用then()中的第一个函数,此时的参数即为resolve()传的参数
//当对象状态转变为失败状态的时候调用then()中的第二个函数,此时的参数即为reject()传的参数
ajax(true).then(function (msg) {
  alert(msg);
}, function (msg) {
  alert(msg);
})

其中的 .then(fn,fn) 可以换一种写法 使用catch如下:

ajax(true).then(function (msg) {
  alert(msg);
}).catch(function (msg) {
  alert(msg);
})

即 .then(fn1,fn2) 等价于 .then(fn1).catch(fn2)。

我们还可以连续使用then,每一次执行该方法时总是会返回一个 Promise 对象,在 then()参数函数中的返回值,可以作为后续操作的参数。

ajax(true).then(function (message) {
    return message;
}).then(function (message) {
    return message  + ' World';
}).then(function (message) {
    return message + '!';
}).then(function (message) {
    alert(message);
});  // Hello World !


Promise.all和Promise.race

  • Promise.all([pro1,pro2...]).then(fn)  ——  可以接收一个 Promise 对象的数组作为参数,当这个数组里面所有的 Promise 对象都变为成功状态时,才会执行then中的函数fn
  • Promise.race([pro1,pro2...]).then(fn)  ——  可以接收一个 Promise 对象的数组作为参数,一旦这个数组里面有一个 Promise 对象变为成功状态时,就执行then中的函数fn,之后就不再关心数组中剩余的Promise对象状态的改变,即剩余Promise 对象状态改变时不会触发fn函数的调用。

举例说明:

Promise.all([pro1,pro2...]).then(fn) 的使用:当请求的所有图片加载完之后才在页面显示出来。

{
  // 所有图片加载完再添加到页面
  function loadImg(src){
    return new Promise((resolve,reject)=>{
      let img=document.createElement('img');
      img.src=src;
      img.onload=function(){
        resolve(img);
      }
      img.onerror=function(err){
        reject(err);
      }
    })
  }

  function showImgs(imgs){
    imgs.forEach(function(img){
      document.body.appendChild(img);
    })
  }
  // .all 把所有的Promise实例当做一个处理
  // 当所有的Promise对象状态都变为成功状态后才执行下一步then
  Promise.all([
    loadImg('./img1.jpg'),
    loadImg('./img2.jpg'),
    loadImg('./img3.jpg')
  ]).then(showImgs)

}

Promise.race([pro1,pro2...]).then(fn)的使用:当请求图片中的一个加载完之后就显示在页面上。

{
  // 有一个图片加载完就添加到页面
  function loadImg(src){
    return new Promise((resolve,reject)=>{
      let img=document.createElement('img');
      img.src=src;
      img.onload=function(){
        resolve(img);
      }
      img.onerror=function(err){
        reject(err);
      }
    })
  }

  function showImgs(img){
    let p=document.createElement('p');
    p.appendChild(img);
    document.body.appendChild(p)
  }
  // .race 指多个状态中有一个状态率先改变时,race实例就跟着改变(即进行下一步调用then方法或者其他),之后的就不响应不理会了
  Promise.race([
    loadImg('./img1.jpg'),
    loadImg('./img2.jpg'),
    loadImg('./img3.jpg')
  ]).then(showImgs)

}

Promise浏览器兼容现状

在项目中使用Promsie对象,可以使用第三方插件bluebird.js ( github地址:https://github.com/petkaantonov/bluebird )

猜你喜欢

转载自blog.csdn.net/m0_37747665/article/details/82633150
今日推荐