欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

剖析ES6的Promise对象

程序员文章站 2022-07-13 09:19:47
...

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浏览器兼容现状

剖析ES6的Promise对象

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

相关标签: Promise ES6