ES6 特性

?詹亮 - site : https://github.com/lzhanforgit/H5Resources

ES6

第一部分

  1. 塊級(jí)元素 let

    1. let

    let聲明的變量不會(huì)自動(dòng)提升到當(dāng)前函數(shù)作用域的頂部

    如果一個(gè)標(biāo)識(shí)符在當(dāng)前作用域里已經(jīng)存在铅匹,那么再用 let 聲明相同的標(biāo)識(shí)符或拋出錯(cuò)誤

  2. 正則表達(dá)式

    1. test

      test 返回 Boolean吱殉,查找對(duì)應(yīng)的字符串中是否存在模式矫夯。

      {
         let rgx=new RegExp(/^\d+\w+$/i);
         //let rgx=new RegExp(/^[a-z]+$/i);
         var s='343435wwwfdfd3434';
      
         var f=rgx.test(s);
         console.log(f);
      }
      
      
    2. exec

      exec 查找并返回當(dāng)前的匹配結(jié)果昔瞧,并以數(shù)組的形式返回此虑。

      exec 方法受參數(shù) g 的影響。若指定了 g脓钾,則下次調(diào)用 exec 時(shí)尼夺,會(huì)從上個(gè)匹配的 lastIndex 開(kāi)始查找

      {
         let rgx=new RegExp(/hello/g);
         var s='hi hello world,hello china';
      
         var res=rgx.exec(s);
         console.log(res)
         var res=rgx.exec(s);
         console.log(res)
      }
      
    3. match

      match 這個(gè)方法有點(diǎn)像 exec,但:exec 是 RegExp 對(duì)象的方法绍些;math 是 String 對(duì)象的方法捞慌。
      二者還有一個(gè)不同點(diǎn),如果指定了參數(shù) g遇革,那么 match 一次返回所有的結(jié)果卿闹。

       let rgx=new RegExp(/hello/g);
         var s='hi hello world,hello china,hello';
      
         var res=s.match(rgx);
         console.log(res)
         //[ 'hello', 'hello', 'hello' ]
      
    4. replace

      let rgx=new RegExp(/helloo/);
      var s='hi hello world';
      
      s=s.replace(/[e,o]/g,'A');
      console.log(s)
      
  3. 擴(kuò)展運(yùn)算符

    擴(kuò)展運(yùn)算符用三個(gè)點(diǎn)號(hào)表示,功能是把數(shù)組或類數(shù)組對(duì)象展開(kāi)成一系列用逗號(hào)隔開(kāi)的值

    var foo = function(a, b, c) {
        console.log(a);
        console.log(b);
        console.log(c);
    }
    
    var arr = [1, 2, 3];
    
    //傳統(tǒng)寫(xiě)法
    foo(arr[0], arr[1], arr[2]);
    
    //使用擴(kuò)展運(yùn)算符
    foo(...arr);
    //1
    //2
    //3
    

    特殊應(yīng)用場(chǎng)景:

     //數(shù)組深拷貝
    
     var arr1=[];
     var arr2=[4,5,6];
     Array.prototype.push.apply(arr1, arr2);
    
    
     console.log(arr1);
    
     console.log(arr1==arr2);//false
    
    //數(shù)組深拷貝
    
    var arr2 = arr;
    var arr3 = [...arr];
    console.log(arr===arr2); //true, 說(shuō)明arr和arr2指向同一個(gè)數(shù)組
    console.log(arr===arr3); //false, 說(shuō)明arr3和arr指向不同數(shù)組
    
    //把一個(gè)數(shù)組插入另一個(gè)數(shù)組字面量
    var arr4 = [...arr, 4, 5, 6];
    console.log(arr4);//[1, 2, 3, 4, 5, 6]
    
    //字符串轉(zhuǎn)數(shù)組
    var str = 'love';
    var arr5 = [...str];
    console.log(arr5);//[ 'l', 'o', 'v', 'e' ]
    
  4. Math 擴(kuò)展

    var num=-123.008;
    console.log(Math.floor(num));//-124
    console.log(Math.trunc(num));//-123
    console.log(~~num);//-123
    
  5. 數(shù)組的擴(kuò)展

    1. 補(bǔ)充數(shù)組知識(shí)...

    2. Array.from方法用于將類數(shù)組轉(zhuǎn)為真正的數(shù)組

      // 'use strict';
      function show(a=1,b=10,c=100) {
          arguments[1]=800;
          console.log(a+'>>'+b+'>>'+c);
          arguments[1]=800;
          //var args=(new Array).slice.call(arguments,0);
          //var args=Array.prototype.slice.call(arguments,0);
          var args=Array.from(arguments);
          args.sort();
          console.log(args);
          console.log(a+'>>'+b+'>>'+c);
      }
      show(400,200,300);
      

      Array.from還可以接受第二個(gè)參數(shù)萝快,作用類似于數(shù)組的map方法锻霎,用來(lái)對(duì)每個(gè)元素進(jìn)行處理,將處理后的值放入返回的數(shù)組揪漩。

      var s='123';
      var sarr=Array.from(s,x=>x*x);
      console.log(sarr);
      
      var arr1=[];
      var arr2=[4,5,6];
      arr2=arr2.map(function (x) {
          return x*x
      })
      console.log(arr2);
      
    3. 數(shù)組實(shí)例的copyWithin()

      >數(shù)組實(shí)例的copyWithin方法旋恼,在當(dāng)前數(shù)組內(nèi)部,將指定位置的成員復(fù)制到其他位置(會(huì)覆蓋原有成員)奄容,然后返回當(dāng)前數(shù)組冰更。也就是說(shuō)产徊,使用這個(gè)方法,會(huì)修改當(dāng)前數(shù)組蜀细。
      
         ```
         Array.prototype.copyWithin(target, start = 0, end = this.length)
         ```
      

      它接受三個(gè)參數(shù)舟铜。

         * target(必需):從該位置開(kāi)始替換數(shù)據(jù)。
         * start(可選):從該位置開(kāi)始讀取數(shù)據(jù)奠衔,默認(rèn)為0谆刨。如果為負(fù)值,表示倒數(shù)归斤。
         * end(可選):到該位置前停止讀取數(shù)據(jù)痊夭,默認(rèn)等于數(shù)組長(zhǎng)度。如果為負(fù)值脏里,表示倒數(shù)她我。
      
      // 將3號(hào)位復(fù)制到0號(hào)位
      [1, 2, 3, 4, 5].copyWithin(0, 3, 4)
      // [4, 2, 3, 4, 5]
      
      // -2相當(dāng)于3號(hào)位,-1相當(dāng)于4號(hào)位
      [1, 2, 3, 4, 5].copyWithin(0, -2, -1)
      // [4, 2, 3, 4, 5]
      
      // 將3號(hào)位復(fù)制到0號(hào)位
      [].copyWithin.call({length: 5, 3: 1}, 0, 3)
      // {0: 1, 3: 1, length: 5}
      
      // 將2號(hào)位到數(shù)組結(jié)束迫横,復(fù)制到0號(hào)位
      var i32a = new Int32Array([1, 2, 3, 4, 5]);
      i32a.copyWithin(0, 2);
      // Int32Array [3, 4, 5, 4, 5]
      
      // 對(duì)于沒(méi)有部署TypedArray的copyWithin方法的平臺(tái)
      // 需要采用下面的寫(xiě)法
      [].copyWithin.call(new Int32Array([1, 2, 3, 4, 5]), 0, 3, 4);
      // Int32Array [4, 2, 3, 4, 5]
      
    4. 數(shù)組實(shí)例的includes()

      Array.prototype.includes方法返回一個(gè)布爾值番舆,表示某個(gè)數(shù)組是否包含給定的值,
      與字符串的includes方法類似员淫。該方法屬于ES7合蔽,但Babel轉(zhuǎn)碼器已經(jīng)支持。

      var arr=[1,2,3,4,50,60,70,80,90];
      
      
      console.log(arr.includes(50));//true
      
  6. 箭頭操作符

    //demo-1
    var arr=[1,2,3];
    
    arr.foreach(v=>console.log(v));
    
    //demo-2
    var max=function (a,b,callback) {
        callback(b);
    }
    
    max(10,20,r=>{
        r=r*r;
        console.log(r);
    })
    

    鏈接:https://imququ.com/post/arrow-function-in-es6.html

  7. class

    //類的定義
    class Animal {
    //ES6中新型構(gòu)造器
    constructor(name) {
        this.name = name;
    }
    //實(shí)例方法
    sayName() {
        console.log('My name is '+this.name);
    }
    }
    //類的繼承
    class Programmer extends Animal {
    constructor(name) {
        //直接調(diào)用父類構(gòu)造器進(jìn)行初始化
        super(name);
    }
    program() {
        console.log("I'm coding...");
    }
    }
    //測(cè)試我們的類
    var animal=new Animal('dummy'),
    wayou=new Programmer('wayou');
    animal.sayName();//輸出 ‘My name is dummy’
    wayou.sayName();//輸出 ‘My name is wayou’
    wayou.program();//輸出 ‘I'm coding...’
    
  8. 字符串模板介返、字符串置換

    注意是反引號(hào)"`"

    let s=`hello
                world`;
    
    console.log(s.length);
    
    console.log(s);
    
    let s=`hello
                    world`.trim();  //去除前拴事、后空格
    
    
    //產(chǎn)生一個(gè)隨機(jī)數(shù)
    var num=Math.random();
    //將這個(gè)數(shù)字輸出到console
    console.log(`your num is ${num}`);
    

    模板

    let name='book';
    
    let count=10,
        price=1.2345;
    
    let s=`${name} cost ${count*price.toFixed(3)} `;
    
    console.log(s);
    

    模板自變量定義多行標(biāo)簽

    window.onload=function () {
            let div=document.querySelector('#table');
    
            let books=[
                {name:'001',price:12},
                {name:'002',price:120},
                {name:'003',price:1200},
                {name:'004',price:12000}
            ]
    
            let s='';
    
            for(let i=0;i<books.length;i++){
                s+=`<tr>
                    <td>${books[i].name}</td>
                    <td>${books[i].price}</td>
                    </tr>`;
    
            }
    
            div.innerHTML=s;
        }
    
  9. 解構(gòu)
    自動(dòng)解析數(shù)組或?qū)ο笾械闹怠1热缛粢粋€(gè)函數(shù)要返回多個(gè)值圣蝎,常規(guī)的做法是返回一個(gè)對(duì)象刃宵,將每個(gè)值做為這個(gè)對(duì)象的屬性返回。但在ES6中徘公,利用解構(gòu)這一特性牲证,可以直接返回一個(gè)數(shù)組,然后數(shù)組中的值會(huì)自動(dòng)被解析到對(duì)應(yīng)接收該值的變量中关面。

    var [x,y]=getVal(),//函數(shù)返回值的解構(gòu)
        [name,,age]=['wayou','male','secrect'];//數(shù)組解構(gòu)
    
    function getVal() {
        return [ 1, 2 ];
    }
    
    console.log('x:'+x+', y:'+y);//輸出:x:1, y:2
    console.log('name:'+name+', age:'+age);//輸出: name:wayou, age:secrect
    
  10. 函數(shù)

    1. 函數(shù)默認(rèn)參數(shù)值
    ```
    function  show(name='helen') {
        var n=name;
        console.log(`name is ${name}`);
    }
    show('tom');
    ```
    
    >當(dāng)使用 ECMAScript 6 的默認(rèn)參數(shù)時(shí)坦袍,arguments對(duì)象的表現(xiàn)和 ECMAScript 5 的嚴(yán)格模式一致,不管函數(shù)是否顯式設(shè)定為嚴(yán)格模式等太。默認(rèn)參數(shù)的存在會(huì)使 arguments 對(duì)象對(duì)該命名參數(shù)解綁捂齐。

    ```
    function getValue() {
        return 5;
    }

    function add(first, second = getValue()) {
        return first + second;
    }

    console.log(add(1, 1));     // 2
    console.log(add(1));        // 6
    ```
2. 函數(shù)不定參數(shù)
    不定參數(shù)是在函數(shù)中使用命名參數(shù)同時(shí)接收不定數(shù)量的未命名參數(shù)。這只是一種語(yǔ)法糖缩抡,在以前的JavaScript代碼中我們可以通過(guò)arguments變量來(lái)達(dá)到這一目的奠宜。不定參數(shù)的格式是三個(gè)句點(diǎn)后跟代表所有不定參數(shù)的變量名。比如下面這個(gè)例子中,…x代表了所有傳入add函數(shù)的參數(shù)压真。
x為數(shù)組對(duì)象

    ```
    function add(...x){
        x.forEach(i=>console.log(i))
        return x.reduce((m,n)=>m+n);
    }
    //傳遞任意個(gè)數(shù)的參數(shù)
    console.log(add(1,2,3));//輸出:6
    console.log(add(1,2,3,4,5));//輸出:15
    ```
3. 拓展參數(shù)

    ```
    var people=['Wayou','John','Sherlock'];
    //sayHello函數(shù)本來(lái)接收三個(gè)單獨(dú)的參數(shù)人妖娩嚼,人二和人三
    function sayHello(people1,people2,people3){
        console.log(`Hello ${people1},${people2},${people3}`);
    }
    //但是我們將一個(gè)數(shù)組以拓展參數(shù)的形式傳遞,它能很好地映射到每個(gè)單獨(dú)的參數(shù)
    sayHello(...people);//輸出:Hello Wayou,John,Sherlock

    //而在以前滴肿,如果需要傳遞數(shù)組當(dāng)參數(shù)岳悟,我們需要使用函數(shù)的apply方法
    sayHello.apply(null,people);//輸出:Hello Wayou,John,Sherlock
    ```
  1. for of 值遍歷
    我們都知道for in 循環(huán)用于遍歷數(shù)組,類數(shù)組或?qū)ο笃貌睿珽S6中新引入的for of循環(huán)功能相似竿音,不同的是每次循環(huán)它提供的不是序號(hào)而是值。

    var someArray = [ "a", "b", "c" ];
    
    for (v of someArray) {
        console.log(v);//輸出 a,b,c
    }
    
  2. 模塊
    測(cè)試不通過(guò)拴驮??柴信?套啤??随常?潜沦??

[參考文章](http://blog.csdn.net/lihongxun945/article/details/49031383).
  1. 集合

    在ES5中绪氛,Array和JSON 可以這么寫(xiě):

    var foo={};
    var n=12;
    foo[12]='tom';
    
    foo.age=12;
    console.log(foo[n]);    // tom
    console.log(foo['12']); //tom
    //在內(nèi)部唆鸡,數(shù)字類型的鍵會(huì)被轉(zhuǎn)化為字符串,所以 map["12"] 和 map[12] 引用了相同的屬性枣察。
    
    console.log(foo.age);   //12
    
    

    數(shù)組方式存在的問(wèn)題

    var foo=[];
    
    console.log(typeof foo)
    foo['name']='tom';
    foo[1]=12;
    
    console.log(foo['name']);   //tom
    console.log(foo[1]);        //12
    
    console.log(foo.length);    //2
    
    console.log(foo[0]);        //undefined
    
    //-------------------
    
    var person1={};
    var person2={};
    
    foo[person1]='onic';
    
    console.log(foo[person1]);  //onic
    console.log(foo[person2]);  //這里還是onic
    
    

    那開(kāi)始介紹SET和MAP

    1. set

      ECMAScript 6 中的 set 類型是一個(gè)包含無(wú)重復(fù)元素的有序列表争占。Set 允許對(duì)內(nèi)部某元素是否存在進(jìn)行快速檢查,使得元素的追蹤操作效率更高序目。

      set 由 new Set() 語(yǔ)句創(chuàng)建并通過(guò)調(diào)用 add() 方法來(lái)向 set 中添加項(xiàng)臂痕。你還可以查看 set 的 size 屬性來(lái)獲取項(xiàng)的數(shù)目:

      let set=new Set();
      
      set.add(12);
      set.add(13);
      
      
      console.log(set.size);  //2
      
      set.add(13);
      
      console.log(set.size);  //應(yīng)為set內(nèi)容不允許出現(xiàn)重復(fù),所以結(jié)果還是2
      

      因?yàn)?key1 和 key2 不會(huì)轉(zhuǎn)換為字符串猿涨,所以它們 set 認(rèn)為兩者都是唯一的(記住握童,如果它們被轉(zhuǎn)換為字符串,那么值都是 "[object Object]")叛赚。

      let set = new Set(),
          key1 = {},
          key2 = {};
      
      set.add(key1);
      set.add(key2);
      
      console.log(set.size);    // 2
      

      你可以使用數(shù)組來(lái)初始化一個(gè) set澡绩,而且 Set 構(gòu)造函數(shù)會(huì)確保使用數(shù)組中唯一存在的元素。例如:

      let set = new Set([1, 2, 3, 4, 5, 5, 5, 5]);
      console.log(set.size);    // 5
      
      console.log(set.has(1));  //true
      
      set.delete(2);
      
      console.log(set.size);    // 4
      
      set.clear();
      
      console.log(set.size);    // 0
      
      
      
      set.forEach(function (v,k,_set) {
      //其中v,k的值相同俺附,因?yàn)閟et沒(méi)有key肥卡,為了保持和數(shù)組的forEach方法同步
          console.log(_set)
      })
      

      利用擴(kuò)展運(yùn)算符,將set轉(zhuǎn)化為數(shù)組

      let set = new Set([1, 2, 3, 3, 3, 4, 5]),
          array = [...set];
      
      

      ***利用這個(gè)特性昙读,可以很容易實(shí)現(xiàn)召调,去掉數(shù)組中的重復(fù)項(xiàng)

      //items為含有重復(fù)項(xiàng)的數(shù)組
      function eliminateDuplicates(items) {
          return [...new Set(items)];
      }
      
    2. map

      let map = new Map();
      map.set("title", "Understanding ES6");
      map.set("year", 2016);
      
      console.log(map.get("title"));      // "Understanding ES6"
      console.log(map.get("year"));       // 2016
      console.log(map.size);              // 2
      
      
      
      • has(key) - 判斷給定的 key 是否在 map 中存在
      • delete(key) - 移除 map 中的 key 及對(duì)應(yīng)的值
      • clear() - 移除 map 中所有的鍵值對(duì)

      map也可以用數(shù)組初始化,也可以使用forEach()

      let map = new Map([["name", "Nicholas"], ["age", 25]]);
      
http://www.cnblogs.com/Wayou/p/es6_new_features.html

第二部分

  1. 深入解析 ES6:Generator

    先上一段代碼

     ```
     function* quips(name) {
         yield `hello ${name} !`;
         yield "i hope you are enjoying the blog posts";
         if (name.startsWith("X")) {
             yield "it's cool how your name starts with X, " + name;
         }
         yield "see you later!";
     }
     ```
    

    解釋

    1. 通常的函數(shù)以 function 開(kāi)始,但 Generator 函數(shù)以 function* 開(kāi)始唠叛。
    2. 在 Generator 函數(shù)內(nèi)部只嚣,yield 是一個(gè)關(guān)鍵字,和 return 有點(diǎn)像艺沼。不同點(diǎn)在于册舞,所有函數(shù)(包括 Generator 函數(shù))都只能返回一次,而在 Generator 函數(shù)中可以 yield 任意次障般。yield 表達(dá)式暫停了 Generator 函數(shù)的執(zhí)行调鲸,然后可以從暫停的地方恢復(fù)執(zhí)行。

    接下來(lái)調(diào)用

     var iterator=quips('lzhan');
    
    1. Generator 函數(shù)的調(diào)用方法與普通函數(shù)一樣:quips("lzhan")挽荡,但調(diào)用一個(gè) Generator 函數(shù)時(shí)并沒(méi)有立即執(zhí)行藐石,而是返回了一個(gè) Generator 對(duì)象(上面代碼中的 iterator),這時(shí)函數(shù)就立即暫停在函數(shù)代碼的第一行定拟。

    2. 每次調(diào)用 Generator 對(duì)象的 .next() 方法時(shí)于微,函數(shù)就開(kāi)始執(zhí)行,直到遇到下一個(gè) yield 表達(dá)式為止青自。

    這就是為什么我們每次調(diào)用 iterator.next() 時(shí)都會(huì)得到一個(gè)不同的字符串株依,這些都是在函數(shù)內(nèi)部通過(guò) yield 表達(dá)式產(chǎn)生的值。

    1. 當(dāng)執(zhí)行最后一個(gè) iterator.next() 時(shí)延窜,就到達(dá)了 Generator 函數(shù)的末尾恋腕,所以返回結(jié)果的 .done屬性值為 true,并且 .value 屬性值為 undefined逆瑞。

    改進(jìn)荠藤、循環(huán)輸出

    var iterator=quips('lzhan');
    var f=iterator.next();
    while (!f.done){
        console.log(f.value);
        f=iterator.next()
    }
    
    1. 從技術(shù)層面上講,每當(dāng) Generator 函數(shù)執(zhí)行遇到 yield 表達(dá)式時(shí)获高,函數(shù)的棧幀 — 本地變量商源,函數(shù)參數(shù),臨時(shí)值和當(dāng)前執(zhí)行的位置谋减,就從堆棧移除牡彻,但是 Generator 對(duì)象保留了對(duì)該棧幀的引用,所以下次調(diào)用 .next() 方法時(shí)出爹,就可以恢復(fù)并繼續(xù)執(zhí)行庄吼。

    2. 值得提醒的是 Generator 并不是多線程。在支持多線程的語(yǔ)言中严就,同一時(shí)間可以執(zhí)行多段代碼总寻,并伴隨著執(zhí)行資源的競(jìng)爭(zhēng),執(zhí)行結(jié)果的不確定性和較好的性能梢为。而 Generator 函數(shù)并不是這樣渐行,當(dāng)一個(gè) Generator 函數(shù)執(zhí)行時(shí)轰坊,它與其調(diào)用者都在同一線程中執(zhí)行,每次執(zhí)行順序都是確定的祟印,有序的肴沫,并且執(zhí)行順序不會(huì)發(fā)生改變。與線程不同蕴忆,Generator 函數(shù)可以在內(nèi)部的 yield 的標(biāo)志點(diǎn)暫停執(zhí)行颤芬。

  2. 解決異步問(wèn)題

    異步 API 通常都需要一個(gè)回調(diào)函數(shù),這意味著每次你都需要編寫(xiě)一個(gè)匿名函數(shù)來(lái)處理異步結(jié)果套鹅。如果同時(shí)處理三個(gè)異步事務(wù)站蝠,我們看到的是三個(gè)縮進(jìn)層次的代碼,而不僅僅是三行代碼卓鹿。

    異步情況:讀取三個(gè)文本文檔

    var fs=require('fs');
    function  readFile() {
        var s='';
        fs.readFile('./txta.txt',function (error,data) {
            s+=data;
            console.log(s);
        });
        fs.readFile('./txtb.txt',function (error,data) {
            s+=data;
            console.log(s);
        });
        fs.readFile('./txtc.txt',function (error,data) {
            s+=data;
            console.log(s);
        });
        return s;
    }
    var result=readFile();
    console.log('end...'+result);
    

    運(yùn)行結(jié)果每次各不相同*****

    利用回調(diào)

    var fs=require('fs');
    function  readFile(callback) {
        var s='';
        fs.readFile('./txta.txt',function (error,data) {
            s+=data;
            console.log('a: '+s);
            fs.readFile('./txtb.txt',function (error,data) {
                s+=data;
                console.log('b: '+s);
                fs.readFile('./txtc.txt',function (error,data) {
                    s+=data;
                    console.log('c: '+s);
                    callback (s);
                });
    
            });
        });
    }
    

    //函數(shù)調(diào)用
    readFile(function (result) {
    console.log('end...'+result);
    });

    異步 API 通常都有錯(cuò)誤處理的約定菱魔,不同的 API 有不同的約定。大多數(shù)情況下吟孙,錯(cuò)誤是默認(rèn)丟棄的豌习,甚至有些將成功也默認(rèn)丟棄了。

    Generator 給我們帶來(lái)了希望拔疚,我們可以不再采用上面的方式。

    Q.async()是一個(gè)將 Generator 和 Promise 結(jié)合起來(lái)處理異步代碼的實(shí)驗(yàn)性嘗試既荚,讓我們的異步代碼類似于相應(yīng)的同步代碼稚失。

    改進(jìn)后代碼

    var fs=require('fs');
        function run(gen) {
        var gen_obj = gen(resume);
        function resume() {
            gen_obj.next(arguments);
        }
        gen_obj.next();
    }
    
    run(function* gen(resume) {
        var ret, err, data;
        ret = yield fs.readFile('./txta.txt', resume);
        console.log(ret);
        err = ret[0];
        data = ret[1];
        if (err) {
            console.log(err);
        } else {
            console.log(data.toString());
        }
    
        ret = yield fs.readFile('./txtb.txt', resume);
        err = ret[0];
        data = ret[1];
        if (err) {
            console.log(err);
        } else {
            console.log(data.toString());
        }
    });
    
    
  1. Promises
    ES6 原生提供了 Promise 對(duì)象。

    所謂 Promise恰聘,就是一個(gè)對(duì)象句各,用來(lái)傳遞異步操作的消息。它代表了某個(gè)未來(lái)才會(huì)知道結(jié)果的事件(通常是一個(gè)異步操作)晴叨,并且這個(gè)事件提供統(tǒng)一的 API凿宾,可供進(jìn)一步處理。

    回調(diào)函數(shù)真正的問(wèn)題在于他剝奪了我們使用 return 和 throw 這些關(guān)鍵字的能力兼蕊。而 Promise 很好地解決了這一切初厚。

    Promise 對(duì)象有以下兩個(gè)特點(diǎn)。

    (1)對(duì)象的狀態(tài)不受外界影響孙技。Promise 對(duì)象代表一個(gè)異步操作产禾,有三種狀態(tài):Pending(進(jìn)行中)、Resolved(已完成牵啦,又稱 Fulfilled)和 Rejected(已失斞乔椤)。只有異步操作的結(jié)果哈雏,可以決定當(dāng)前是哪一種狀態(tài)楞件,任何其他操作都無(wú)法改變這個(gè)狀態(tài)衫生。這也是 Promise 這個(gè)名字的由來(lái),它的英語(yǔ)意思就是「承諾」土浸,表示其他手段無(wú)法改變罪针。

    (2)一旦狀態(tài)改變,就不會(huì)再變栅迄,任何時(shí)候都可以得到這個(gè)結(jié)果站故。Promise 對(duì)象的狀態(tài)改變,只有兩種可能:從 Pending 變?yōu)?Resolved 和從 Pending 變?yōu)?Rejected毅舆。只要這兩種情況發(fā)生西篓,狀態(tài)就凝固了,不會(huì)再變了憋活,會(huì)一直保持這個(gè)結(jié)果岂津。就算改變已經(jīng)發(fā)生了,你再對(duì) Promise 對(duì)象添加回調(diào)函數(shù)悦即,也會(huì)立即得到這個(gè)結(jié)果吮成。這與事件(Event)完全不同,事件的特點(diǎn)是辜梳,如果你錯(cuò)過(guò)了它粱甫,再去監(jiān)聽(tīng),是得不到結(jié)果的作瞄。

    Promise 也有一些缺點(diǎn)茶宵。

    首先,無(wú)法取消 Promise宗挥,一旦新建它就會(huì)立即執(zhí)行乌庶,無(wú)法中途取消。

    其次契耿,如果不設(shè)置回調(diào)函數(shù)瞒大,Promise 內(nèi)部拋出的錯(cuò)誤,不會(huì)反應(yīng)到外部搪桂。

    第三透敌,當(dāng)處于 Pending 狀態(tài)時(shí),無(wú)法得知目前進(jìn)展到哪一個(gè)階段(剛剛開(kāi)始還是即將完成)踢械。

    基本的 api

    Promise.resolve()
    
    Promise.reject()
    
    Promise.prototype.then()
    
    Promise.prototype.catch()
    
    Promise.all() // 所有的完成
    
    var p = Promise.all([p1,p2,p3]);
    Promise.race() // 競(jìng)速拙泽,完成一個(gè)即可
    

    demo

    function helloWorld (ready) {
    return new Promise(function (resolve, reject) {
        if (ready) {
            resolve("Hello World!");
        } else {
            reject("Good bye!");
        }
    });
    }
    //then有兩個(gè)方法,第一個(gè)為SUCCESS,第二個(gè)為ERROR方法
    helloWorld(true)
    .then(function (message) {
            // console.log(message);
            return message;
        },
        function (error) {
            // console.log(error);
            return message;
        })
    .then(function (message) {
        console.log('success '+message);
        },
        function (message) {
            console.log('error '+message);
        })
    

    異常處理-catch

    catch 方法是 then(onFulfilled, onRejected) 方法當(dāng)中 onRejected 函數(shù)的一個(gè)簡(jiǎn)單的寫(xiě)法裸燎,也就是說(shuō)可以寫(xiě)成 then(fn).catch(fn)顾瞻,相當(dāng)于 then(fn).then(null, fn)。使用 catch 的寫(xiě)法比一般的寫(xiě)法更加清晰明確德绿。

    demo

        helloWorld(false)
        .then(function (message) {
                // console.log(message);
                return message;
            },
            function (error) {
                // console.log(error);
                return error;
            })
        .then(function (message) {
                console.log('success '+message);
            })
        //    以下情況一和情況二等價(jià)
        //    情況一
        // .catch(function (message) {
        //     console.log('error '+message);
        // })
        //情況二
        .then(null,function (message) {
            console.log('error '+message);
        })
    
    
      var show=(x,y)=>{
          return new Promise((resolve, reject)=> {
              if (x>y) {
                  setTimeout(function () {
                      let k=x+y;
                      resolve(k);
                  })
              } else {
                  reject("Good bye!");
              }
          })
      }
    
      show(100,150).then(data=>{
          console.log(data);
      },data=>{
          console.log(data);
      };
      )
    

    Promise.all

    Promise.all 可以接收一個(gè)元素為 Promise 對(duì)象的數(shù)組作為參數(shù)荷荤,當(dāng)這個(gè)數(shù)組里面所有的 Promise 對(duì)象都變?yōu)?resolve 時(shí)退渗,該方法才會(huì)返回。

    demo

        var p1 = new Promise(function (resolve) {
        setTimeout(function () {
            resolve("Hello");
        }, 3000);
        });
    
        var p2 = new Promise(function (resolve) {
            setTimeout(function () {
                resolve("World");
            }, 1000);
        });
    
        Promise.all([p1, p2]).then(function (result) {
            console.log(result); // ["Hello", "World"]
        });
    
    

    //雖然 p2 的速度比 p1 要快蕴纳,但是 Promise.all 方法會(huì)按照數(shù)組里面的順序?qū)⒔Y(jié)果返回会油。

    還有一個(gè)和 Promise.all 相類似的方法 Promise.race,它同樣接收一個(gè)數(shù)組古毛,不同的是只要該數(shù)組中的 Promise 對(duì)象的狀態(tài)發(fā)生變化(無(wú)論是 resolve 還是 reject)該方法都會(huì)返回翻翩。

    如果要兼容舊的瀏覽器,建議可以尋找一些第三方的解決方案稻薇,例如 jQuery 的 $.Deferred嫂冻。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市塞椎,隨后出現(xiàn)的幾起案子桨仿,更是在濱河造成了極大的恐慌,老刑警劉巖案狠,帶你破解...
    沈念sama閱讀 222,378評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件服傍,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡骂铁,警方通過(guò)查閱死者的電腦和手機(jī)吹零,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,970評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)拉庵,“玉大人灿椅,你說(shuō)我怎么就攤上這事∶危” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,983評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵泣懊,是天一觀的道長(zhǎng)伸辟。 經(jīng)常有香客問(wèn)我,道長(zhǎng)馍刮,這世上最難降的妖魔是什么信夫? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,938評(píng)論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮卡啰,結(jié)果婚禮上静稻,老公的妹妹穿的比我還像新娘。我一直安慰自己匈辱,他們只是感情好振湾,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,955評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著亡脸,像睡著了一般押搪。 火紅的嫁衣襯著肌膚如雪树酪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 52,549評(píng)論 1 312
  • 那天大州,我揣著相機(jī)與錄音续语,去河邊找鬼。 笑死厦画,一個(gè)胖子當(dāng)著我的面吹牛疮茄,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播根暑,決...
    沈念sama閱讀 41,063評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼购裙!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,991評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤绘趋,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后钾挟,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,522評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,604評(píng)論 3 342
  • 正文 我和宋清朗相戀三年耍贾,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了阅爽。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,742評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡荐开,死狀恐怖付翁,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情晃听,我是刑警寧澤百侧,帶...
    沈念sama閱讀 36,413評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站能扒,受9級(jí)特大地震影響佣渴,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜初斑,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,094評(píng)論 3 335
  • 文/蒙蒙 一辛润、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧见秤,春花似錦频蛔、人聲如沸灵迫。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,572評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)瀑粥。三九已至,卻和暖如春三圆,著一層夾襖步出監(jiān)牢的瞬間狞换,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,671評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工舟肉, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留修噪,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,159評(píng)論 3 378
  • 正文 我出身青樓路媚,卻偏偏與公主長(zhǎng)得像黄琼,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子整慎,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,747評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容

  • 1.es6熟悉嗎脏款,說(shuō)幾個(gè)es6的新增方法 (1)新增聲明命令let和const 在es6中通常用 let 和 co...
    南臺(tái)觀蕓秀閱讀 6,174評(píng)論 0 2
  • 下面是10個(gè)ES6最佳特性,排名不分先后: 1.函數(shù)參數(shù)默認(rèn)值 2.模板字符串 3.多行字符串 4.解構(gòu)賦值 5....
    痛心涼閱讀 258評(píng)論 0 0
  • 為了保證可讀性裤园,本文采用意譯而非直譯撤师,并且對(duì)源代碼進(jìn)行了大量修改拧揽。另外,本文版權(quán)歸原作者所有痒谴,翻譯僅用于學(xué)習(xí)。 E...
    強(qiáng)哥科技興閱讀 224評(píng)論 0 0
  • 變量: let 积蔚,let具有塊級(jí)作用域库倘,存在暫時(shí)性死區(qū)(在塊級(jí)作用域let聲明了一個(gè)變量论矾,它所聲明的變量就被綁定到...
    長(zhǎng)街舊人_ec0d閱讀 137評(píng)論 0 0
  • es6相較之前es5贪壳,增加了許多新的特性闰靴,提高了javascript體驗(yàn),我在es6學(xué)習(xí)和使用的過(guò)程中進(jìn)行了紀(jì)錄配猫。...
    YomonAh閱讀 229評(píng)論 0 2