1. 程式人生 > >es6 promise 和 es7 await

es6 promise 和 es7 await

注意!!!

使用es7 async await presets必須使用stage-3,否則不會執行

1、使用了promise,不使用promise,可以用一個callback,不過如果callback也是一個非同步就會形成回撥地獄

比如

var a = 0;

setTimeout({

             a = 1

             console.log(a);

             setTimeout({

                  a = 2

                  console.log(a);

                  setTimeout({

                       a = 3

                       console.log(3);

                  },1000)

             },1000)

        },1000)

這段程式碼可以使用回撥函式處理一下,程式碼如下

var a = 0;

function callback2(){

                            console.log(a)

                            setTimeout({

                                 a = 3

                             },1000)

                       }

function callback1(){

                  console.log(a)

                  setTimeout({

                       a = 2

                       callback2();                       

                 },1000)

funcition timer(){

     setTimeout({

             a = 1

             callback1();

      },1000) 

}

timer();        

這就形成了回撥地獄,這段程式碼的執行效果是1秒後輸出1,在一秒後輸出2,在一秒後輸出3,這段程式碼與下面的這段程式碼的執行是不一樣的

setTimeout({

             console.log(1);                              

        },1000)

setTimeout({

                  console.log(2);

       },1000)

setTimeout({

                       console.log(3);

      },1000)

這段程式碼是會在一秒後同時輸出1,2,3,不理解的話請參照下方連結

如果你使用promise的話,就不會陷入回撥地獄了

function time(){

      return new Promise(function(resolve,reject){

                setTimeout(function(){

                     a = 1;

                     resolve(a);

                },1000)

      })

}

function callback1(){

       return new Promise(function(resolve,reject){

                setTimeout(function(){

                     a = 2;

                     resolve(a);

                },1000)

      })

}

function callback3(){

       return new Promise(function(resolve,reject){

                setTimeout(function(){

                     a = 3;

                     resolve(a);

                },1000)

      })

}

timer().then(function(data){

     console.log(data)   //一秒後輸出1

     return callback1()

}).then(function(data){

     console.log(data) //一秒後輸出2

     return callback2()

}) .then(function(data){

     console.log(data) //一秒後輸出3

})

這裡使用async await又該怎麼去寫呢,程式碼如下:

var a = 0;

async function time(){

      let response = await new Promise(function(resolve,reject){

                setTimeout(function(){

                     a = 1;

                     resolve(a);

                },1000)

      });

      console.log(response);

      return response;

}

async function callback1(){

      let response = await time()

      return response;

}

all的用法

Promise的all方法提供了並行執行非同步操作的能力,並且在所有非同步操作執行完後才執行回撥。我們仍舊使用上面定義好的runAsync1、runAsync2、runAsync3這三個函式,看下面的例子:

Promise
.all([runAsync1(), runAsync2(), runAsync3()])
.then(function(results){
    console.log(results);
});
  • 1
  • 2
  • 3
  • 4
  • 5

用Promise.all來執行,all接收一個數組引數,裡面的值最終都算返回Promise物件。這樣,三個非同步操作的並行執行的,等到它們都執行完後才會進到then裡面。那麼,三個非同步操作返回的資料哪裡去了呢?都在then裡面呢,all會把所有非同步操作的結果放進一個數組中傳給then,就是上面的results。所以上面程式碼的輸出結果就是: 
這裡寫圖片描述

有了all,你就可以並行執行多個非同步操作,並且在一個回撥中處理所有的返回資料,是不是很酷?有一個場景是很適合用這個的,一些遊戲類的素材比較多的應用,開啟網頁時,預先載入需要用到的各種資源如圖片、flash以及各種靜態檔案。所有的都載入完後,我們再進行頁面的初始化。

https://www.jianshu.com/p/e5225ba4a025

其實很簡單,一定得去理解,非同步重開執行緒嘛,跟ajax其實一樣的

這裡是使用了promise的程式碼

var b = 2

function runAsync(){
    return new Promise(function(resolve,reject){
    setTimeout(function(){
           b = 6
           resolve(b)
    }, 2000);
    })
}

runAsync().then(function(data){console.log(data));    //6

下面使用了es7 async await 的程式碼,其實核心還是promise,只是promise的再次封裝

var b = 2;

async function runAsync(){
    const testResult = await new Promise(function(resolve,reject){
    setTimeout(function(){
           b = 6
           resolve(b)
    }, 2000);
    })

    console.log(testResult);
}

runAsync()    //6

其實真的非常相似,只是捨棄了promise.then更加麻煩的寫法

async、await序列並行處理

序列:等待前面一個await執行後接著執行下一個await,以此類推

async function asyncAwaitFn(str) {
    return await new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(str)
        }, 1000);
    })
}

const serialFn = async () => { //序列執行

    console.time('serialFn')
    console.log(await asyncAwaitFn('string 1'));
    console.log(await asyncAwaitFn('string 2'));
    console.timeEnd('serialFn')
}