ES6进修笔记之Promise

这篇文章只处置惩罚三个题目。
什么是promise?
promise有什么用?
promise怎样用?

1.什么是promise?

关于ES6来讲,就是一个组织函数,可以用new Promise( )来建立Promise实例。

2.promise有什么用?

先设想两个场景:

一,营业中,须要要求背景的两个接口,然则须要第一个返回胜利效果以后再要求第二个接口,这是可能会写成下面这个模样,


    var request  = function(){
        var xhr1 = new XMLHttpRequest();
        xhr1.onreadystatechange = function(){
          if(xhr1.readyState !== 4){
            alert('第一步要求失利了,请重试!');
            return;
          }
          if(xhr1.status === 200){
            console.log('第一步要求胜利了,我们最先下一步吧!');
            var xhr2 = new XMLHttpRequest();
            xhr2.open("GET", url);
            xhr2.onreadystatechange = function(){
              if(xhr2.readyState !== 4){
                alert('第二步要求失利了,请重试!');
                return;
              }
              if(xhr2.status === 200){
    
                //两次要求胜利后做的一些事变....
    
              } else {
                alert('第二步要求失利了,请重试!');
              }
            };
            xhr2.responseType = "json";
            xhr2.setRequestHeader("Accept", "application/json2");
            xhr2.send();
          } else {
            alert('第一步要求失利了,请重试!');
          }
        };
        xhr1.responseType = "json";
        xhr1.setRequestHeader("Accept", "application/json1");
        xhr1.send();
      });
    }
    
    request();

上面代码用xhr对象完成了两次异步要求,代码很长。不过这仅仅是两层回调嵌套,设想一下更多的异步回调依靠有多恐怖…

二,我们都晓得,nodejs的一大特性就是事宜驱动,那就肯定要运用事宜的回调函数来处置惩罚逻辑,多层的回调嵌套也就在所难免。那末你的代码极可能就会写成这个品德,


    async(1,function(value){
      async(value,function(value){
        async(value,function(value){
          async(value,function(value){
            async(value,function(value){
              async(value,function(value){
                async(value,function(value){
                  async(value,function(value){
                    async(value,final);
                  });
                });
              });
            });
          });
        });
      });
    })

就此你掉进了又长又丑的嵌套地狱。

咋办?

用promise(回复了“promise是干啥的”)。

咋用?

往下看。

3.promise 怎样用?

在进修怎样运用Promise的同时,须要不时打仗几个关于它的知识点。能明白最好,明白不了用着用着就明白了。

起首须要相识的是每一个Promise实例都有三种状况:

1.举行中状况 pending
2.胜利状况 resolved
3.失利状况 rejected

同一时间下Promise实例只能有一种状况,且只能转变一次,改完以后就再也不能变了。

变化的门路只需两种,第一,从pending变成resolved;第二,从pending变成rejected。

接下来就一步步的完成一个promise的运用。

第一步,new一个Promise实例。上代码:


    var promise = new Promise(function(resolve,reject){
      if(/*异步实行胜利*/){
        resolve(value)
      } else {
        reject(error)
      }
    });

Promise的组织函数吸收一个函数参数,并传入两个参数resolve,reject离别示意异步操纵实行胜利后的回调函数和异步操纵实行失利后的回调函数。实行resolve(),会将当前promise对象的状况更改成resolved,实行reject()会将当前promise对象的状况更改成rejected。

这时候一个Promise对象已建立完成,异步剧本的效果也已被存在这个Promise对象中了,但它是胜利是失利?我们怎样读取呢?

第二步,then要领。接着上代码:


    var promise = new Promise(function(resolve,reject){
      if(/*异步实行胜利*/){
        resolve(value);
      } else {
        reject(error);
      }
    });
    
    promise.then(function(value){
      console.log(value);
    },function(error){
      console.log(error);
    })

每一个Promise实例都有一个then要领,它就是处置惩罚Promise中存储的异步实行效果的要领。then要领可以接收两个回调函数作为参数。第一个回调函数是Promise对象的状况变成Resolved时挪用,第二个回调函数是Promise对象的状况变成Reject时挪用。个中,第二个函数是可选的,不一定要供应。这两个函数都接收Promise对象传出的值作为参数。

须要特别注重的是then要领的返回值照样一个Promise!这就意味着then要领是支撑链式挪用的。

第三步,catch要领。
catch要领等同于then(null,function(){}),也就是用来处置惩罚rejected状况下Promise数据的。关于catch个人认为记着两点就好。第一,用catch来处置惩罚rejected的Promise;第二,用catch来捕捉之前一切链式挪用中抛出的Error对象,注重是一切,包含Promise组织函数、then要领、链式挪用的then要领、以及之前的catch,这些步骤抛出的毛病都可以被catch捕捉。


    var promise = new Promise(function(resolve,reject){
      if(false){
        resolve(value);
      } else {
        reject(error);
      }
    });
    
    promise
      .then(function(value){
        console.log(value);
      })
      .catch(function(reason){
        console.log(error);
      })

上面代码会输出reject(error)传入的error值,也就是catch的第一种用法。


    var promise = new Promise(function(resolve,reject){
      if(true){
        resolve(value);
      } else {
        reject(error);
      }
    });
    
    promise
      .then(function(value){
        console.log(value);
        console.log(x);
      })
      .catch(function(reason){
        console.log(reason);
      })

上面代码会将Promise的状况改成resolved,并实行then要领,在then要领中会抛出一个x变量未定义的毛病,并由catch要领捕捉到并打印出来,这就是catch的第二个用法。

至此实际上我们已学会了Promise的基本运用。接下来再进修两个比较好用的要领。

第一个,Promise.all要领。

该要领可以并行运转异步要领,并在效果都返回以后举行一致处置惩罚,并返回一个新的Promise对象。


    var p = Promise.all([p1, p2, p3]);

上面代码中,Promise.all要领接收一个“数组”作为参数,p1、p2、p3都是Promise对象的实例。

p的状况由p1、p2、p3决议,分红两种状况。

(1)只需p1、p2、p3的状况都变成fulfilled,p的状况才会变成fulfilled,此时p1、p2、p3的返回值构成一个数组,传递给p的回调函数。(fulfilled可以明白为resolved)

(2)只需p1、p2、p3当中有一个被rejected,p的状况就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。


    var p = Promise.all([p1,p2,p3]);
    
    p.then(function(results){
        console.log(results)
    });

当翻开网页时,须要预先加载种种资本如图片、flash以及种种静态文件,一切的都加载完后,我们再举行页面的初始化。这类场景是很合适运用Promise.all的。

第二个,Promise.race要领。

与all要领相似,同样是可以并行运转异步要领,并在效果都返回以后举行一致处置惩罚,并返回一个新的Promise对象。


    var p = Promise.race([p1,p2,p3]);

上面代码中,只需p1、p2、p3当中有一个实例领先转变状况,p的状况就随着转变。谁人领先转变的 Promise 实例的返回值,就传递给p的回调函数,也就是说谁实行的快就返回谁的。

race要领可以增加要求超时的限定。


    //要求某个图片资本
    
    function requestImg(){
        var p = new Promise(function(resolve, reject){
            var img = new Image();
            img.onload = function(){
                resolve(img);
            }
            img.src = 'xxxxxx';
        });
        return p;
    }
    
    //延时函数,用于给要求计时
    
    function timeout(){
        var p = new Promise(function(resolve, reject){
            setTimeout(function(){
                reject('图片要求超时');
            }, 5000);
        });
        return p;
    }
    
    Promise
    .race([requestImg(), timeout()])
    .then(function(results){
        console.log(results);
    })
    .catch(function(reason){
        console.log(reason);
    });

到这,关于Promise的三个题目已解答完了,希望可以为人人进修Promise供应一点协助。

    原文作者:未末辰降
    原文地址: https://segmentfault.com/a/1190000008878538
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞