es6之Promise

Promise 

Promise 是异步编程的一种解决方案。

Promise对象有以下两个特点。

(1)对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是Promise这个名字的由来,它的英语意思就是“承诺”,表示其他手段无法改变。

(2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。如果改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果。这与事 件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。

es5执行异步操作:

{
  // 基本定义
  let ajax=function(es5func){
    console.log('执行');
    setTimeout(function () {
      es5func&&es5func.call()
    }, 1000);
  };
  ajax(function(){
    console.log('timeout1');
  })
}
//执行
// timeout1

Promise

{
  let ajax=function(){
    console.log('执行2');
    return new Promise(function(resolve,reject){
      setTimeout(function () {
        resolve()
      }, 1000);
    })
  };

  ajax().then(function(){
    console.log('timeout2');
  })
}
//执行2
// timeout2

多个异步操作

{
  let ajax=function(){
    console.log('执行3');
    return new Promise(function(resolve,reject){
        resolve()
    })
  };

  ajax()
    .then(function(){
    return new Promise(function(resolve,reject){
        resolve()
    });
  })
    .then(function(){
    console.log('timeout3');
  })
}

Promise 新建后就会立即执行。

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

promise.then(function() {
  console.log('resolved.');
});

console.log('Hi!');

// Promise
// Hi!
// resolved

then方法可以接受两个回调函数作为参数。第一个回调函数是Promise对象的状态变为resolved时调用,第二个回调函数是Promise对象的状态变为rejected时调用。其中,第二个函数是可选的,不一定要提供。这两个函数都接受Promise对象传出的值作为参数。

function timeout(ms) {
  return new Promise((resolve, reject) => {
    setTimeout(resolve, ms, 'done');
  });
}

timeout(100).then((value) => {
  console.log(value);
});
//done

捕获错误:.catch()

func(参数).then(function(value) {
  // ...
}).catch(function(error) {
  // 处理func和 前一个回调函数运行时发生的错误
  console.log('发生错误!', error);
});
{
  let ajax=function(num){
    console.log('执行4');
    return new Promise(function(resolve,reject){
      if(num>5){
        resolve()
      }else{
        throw new Error('出错了')
      }
    })
  }

  ajax(6).then(function(){
    console.log('log',6);
  }).catch(function(err){
    console.log(err);
  });

  ajax(3).then(function(){
    console.log('log',3);
  }).catch(function(err){
    console.log('catch',err);
  });
}
//执行4
// 执行4
// log 6
//  Error: 出错了
// at <anonymous>:8:15
//    at new Promise (<anonymous>)
//    at ajax (<anonymous>:4:12)
//    at <anonymous>:19:3

Promise.all() 

Promise.all方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。

只有Promise.all()中所有实例的状态都变成fulfilled,或者其中有一个变为rejected,才会调用Promise.all方法后面的回调函数。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>
<body>
  <script type="text/javascript">
    {
  // 所有图片加载完再添加到页面
  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);
    })
  }

  Promise.all([
    loadImg('http://img.mukewang.com/52da54ed0001ecfa04120172.jpg'),
    loadImg('http://img.mukewang.com/52da54ed0001ecfa04120172.jpg'),
    loadImg('http://img.mukewang.com/52da54ed0001ecfa04120172.jpg')
  ]).then(showImgs);

}
  </script>
</body>
</html>

Promise.race() 

Promise.race方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例。
只要Promise.race所有实例中有一个实例率先改变状态,状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给回调函数。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>
<body>
  <script type="text/javascript">
    {
 // 有一个图片加载完就添加到页面
  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)
  }

  Promise.race([
    loadImg('http://img.mukewang.com/52da54ed0001ecfa04120172.jpg'),
    loadImg('http://img.mukewang.com/52da54ed0001ecfa04120172.jpg'),
    loadImg('http://img.mukewang.com/52da54ed0001ecfa04120172.jpg')
  ]).then(showImgs)
}
  </script>
</body>
</html>

用promise封装ajax请求

function getJSON (url) {

    return new Promise( (resolve, reject) => {
        var xhr = new XMLHttpRequest();
        xhr.open('GET', url, true);

        xhr.onreadystatechange = function () {
            if (xhr.readyState === 4) {
                if (xhr.status === 200) {
                    resolve(xhr.responseText, xhr);
                } else {
                    var resJson = { code: this.status, response: this.response };
                    reject(resJson, this);
                }
            }
        }

        xhr.send();
    })

}

 

posted @ 2018-06-06 18:26  sunmarvell  阅读(153)  评论(0编辑  收藏  举报