zoukankan      html  css  js  c++  java
  • 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();
        })
    
    }
  • 相关阅读:
    如何找按钮数组在布局中的横竖坐标位置?
    java中使用rmi进行远程方法调用
    测试视频集,各种测试用的视频文件
    如何彻底禁用VS 2008的智能感知功能
    JavaScript秘密花园 Type Casting,undefined,eval,setTimeout,Auto Semicolon Insertion
    JavaScript秘密花园 scope, namespace, constructor, equality and comparisons
    造成内存位置访问无效的一个原因
    depends在VS2008消失了
    12月10日晚的月全食照片
    JavaScript秘密花园 Array, Array Constructor, for in loop, typeof, instanceOf
  • 原文地址:https://www.cnblogs.com/sunmarvell/p/9146675.html
Copyright © 2011-2022 走看看