【Web全棧課程三】ES6特性介紹(下)

ES6特性介紹(下)

ES6新的標準,新的語法特徵:
一、變量/賦值
二、函數
三、數組/json
四、字符串
五、面向對象
六、Promise
七、generator
八、ES7:async/awaitjavascript

《【Web全棧課程二】ES6特性介紹(上)》見:https://segmentfault.com/a/11...java

六、Promise

根本做用,解決異步的操做,將異步操做寫法同步化,是es6提供給咱們的語法糖(內部實現依舊是異步)
同步-串行 簡單、方便 頁面假死的現象
異步-併發 性能高、體驗好es6

使用wamp做爲本地服務器使用
【補充:wamp用法】ajax獲取數據須要使用服務器,項目都放在www裏面,訪問時按照以下對應關係轉換
本地物理地址:c:\wamp64\www
本地網絡地址:http://localhost/ajax

Ajax發送請求
缺點:異步請求邏輯和結果處理邏輯耦合在一塊兒,不便於複用和書寫
clipboard.pngjson

Promise:

同步的簡單寫法實現異步,獲取一條url數據。Promise在ES6中被統一規範,由瀏覽器直接支持,它最大的好處是在異步執行的流程中,把執行代碼和處理結果的代碼清晰地分離segmentfault

let p =new Promise((resolve, reject) => {
  resolve();
  reject();
});
p.then(success=>{},err=>{});

clipboard.png

補充一下ajax和Promise混用的原理,咱們能夠將ajax操做的返回值打印出來,發現裏面有then方法、catch方法,其實它就是一個Promise對象。那麼咱們爲何還要使用Promise?promise的all和race能很好地處理多條異步操做。數組

Promise.all:接收promise數組,在全部異步操做執行完後才執行回調。
Promise.race:接收promise數組,只要有一個異步操做執行完畢就執行回調。
Promise.all([
  $.ajax('/banner_data'),
  $.ajax('/item_data'),
  $.ajax('/users_data'),
  $.ajax('/news_data'),
]).then(arrs=>{
  let [banners,items,users,news]=arrs;
},err=>{});

七、generator 生成器

promise只能提供race和all的邏輯操做,若是咱們要實現更加複雜的異步操做,例如等待a異步操做完成後根據a的結果選擇執行b或者c,使用promise就須要寫不少的嵌套,又不能知足咱們代碼的高可用和可讀性。
這裏先給你們介紹generator提供的解決方案,實際使用中generator並不方便,咱們通常使用async/await,後面會提到。promise

1.generator函數前面有*號瀏覽器

function show(){} //普通函數
    function *show1(){}//generator函數

2.generator函數的特色是可以暫停,等待某個動做(異步操做)完成後繼續執行。何時暫停呢?咱們須要告訴它暫停的時間點,咱們經過yield告訴generator函數暫停,yield也只能在generator函數使用。服務器

//generator函數
    function *show(){
        alert('aaa');
        yield; //函數暫停
        alert('bbb');
    }

    show();

咱們直接調用show(),會發現界面沒有任何效果,和咱們習慣的函數順序執行使用習慣並不相同。generator函數返回的是一個generator對象,須要next()才能運行generator函數。示例:

// 運行generator函數
    let gen = show();
    gen.next(); //彈出aaa
    gen.next(); //彈出bbb

三、generator函數接收參數,返回值。其中,gen.next()返回一個對象,value是yield的返回值,done表明函數是否執行完成。

function *show(){
      alert('aaa');
      //let a = yield 接收next給的參數; yield 55 返回值55
      let a = yield 55;
      alert('bbb'+','+a);//彈出bbb,23
    }
    let gen=show();
    let res1=gen.next();console.log(res1);//{value: 55, done: false}
    let res2=gen.next(23);console.log(res2);//{value: undefined, done: true}

以上執行,有2個點讓人疑惑
一、返回值:yield 55返回給第一個next了
二、接受參數:let a = yield接收的是第二個next傳遞進來的參數

咱們用下面這張圖來很好的解釋這個緣由,紅色圈出來的部分是第一個next的範圍,綠色圈出來的是第二個next的範圍。也就是說yield返回屬於上一個next,接收參數屬於下一個next。
clipboard.png

小結:
一、箭頭函數不能寫generator函數
二、generator只是一個過渡,從例子中看到yield的使用有不少約束,也不符合咱們經常使用的使用習慣。通常使用async/await

八、ES7:async/await

async/await也能夠在執行中暫停,await等待一個異步操做完成後再繼續往下執行,它將異步操做同步化。await必定使用在async函數中,先來直接看下使用方式

async function show() {
    alert('aaa');
    //12是一個數值,不是異步操做,不會進行等待
    await 12;
    alert('bbb');
  }
  show();

一、await後面跟一個異步操做,不然不會進行等待。如上代碼就不會進行等待。
setTimeout不是異步操做,可是若是包成promise,await就會認爲它是一個異步操做,以下代碼彈出aaa後會等待2s後再彈出bbb。

function sleep(){
    return new Promise((resolve,reject)=>{
      setTimeout(()=>{resolve();},2000);
    });
  }
  async function show() {
    alert('aaa');
    await sleep();//等待2s
    alert('bbb');
  }
  show();

二、await進行邏輯操做
咱們在1.txt文件中存放{"a":12,"b":5},實現若是a+b<10則獲取2.txt,不然獲取3.txt,能夠預見到結果會進去獲取3.txt的分支。

//用箭頭函數寫async函數,匿名函數
  (async ()=>{
    let data1 = await $.ajax({url:'../datas/1.txt',dataType:'json'});
    //獲取data1的異步請求已經執行完成
    if(data1.a+data1.b<10){
      let data2 =  await $.ajax({url:'../datas/2.txt',dataType:'json'});
      console.log('2.txt');
      console.log(data2);
    } else {
      let data3 =  await $.ajax({url:'../datas/3.txt',dataType:'json'});
      console.log('3.txt');
      console.log(data3);
    }
  })();

結果以下:
clipboard.png

小結:一、await必定使用在async函數中二、await必須等待一個異步操做,一般等待一個promise

相關文章
相關標籤/搜索