ES6新特性之Async

基本概念

Async其實是一個封裝了自動化執行並返回一個Promise的Generator函數的語法糖。這句話的意思咱們能夠分爲三個部分來解讀:編程

  • 首先它有一個自動化執行,Generator函數是依靠不停的調用.net來依次執行的,Async有一個自動化執行的過程。promise

  • 第二個,它返回一個Promise,也就是說在Async函數裏面咱們拿到它的結果須要調用promise.then。異步

  • Generator函數的語法糖。async

    不添加自動化執行腳本的函數:函數式編程

    function resolveAfter2Seconds(value) {
        return new Promise(resolve => {
            setTimeout(() => {
                resolve(value);
            },2000);
        })
    }
    
    const generator = function* () {
      const value1 = yield resolveAfter2Seconds(1);
      const value2 = yield resolveAfter2Seconds(2);
      console.log(value1);
      console.log(value2);
    };

    Generator自動化執行的腳本:函數

    function co(generatorFunction){
        return new Promise(function(resolve, reject) {
            const generator = generatorFunction();
            function step(nextF) {
                let next;
                try {
                    next = nextF();
                } catch(e) {
                    return reject(e);
                }
                // 若是遍歷已經結束了
                if(next.done) {
                    return resolve(next.value);
                }
                Promise.resolve(next.value).then(function(v) {
                    step(function() {
                        return generator.next(v);
                    });
                },function(e) {
                    step(funciton() {
                        return generator.throw(e);
                    });
                });
            }
            step(function() {
                return generator.next(undefined);
            });
        });
    }
    
    co(generator);
    /*
    (4s後)
    1
    2
    */
    
    
    const async = async function () {
      const value1 = await resolveAfter2Seconds(1);
      const value2 = await resolveAfter2Seconds(2);
      console.log(value1);
      console.log(value2);
    };
    async().then(res => {
      console.log(res);
    })
    
    /*
    (4s後)
    1
    2
    */
    
    async function asyncFunc() {};
    const asyncFunc = async function () {};
    const asyncFunc = async () => {};
    const obj = {
      async asyncFunc() {}
    }

語法

  • 首先,最重要的一點是它返回一個Promise對象,也就是說,在Async裏面,在它後面咱們想要獲得函數的執行結果,必須使用一個.then()。this

    async function asyncGun() {
        return 'Eric';
    }
    
    asyncFunc().then(value => console.log(value));
    // Eric
  • 第二個,await遇到了一個非Promise,直接返回:.net

    async function asyncFunc(){
        return await 'Eric';
    }
    
    asyncFunc().then(value => console.log(value));
    // Eric
  • thenable(帶有then方法的一個函數)對象等同於Promise。code

    class Thenable {
        constructor(timeout) {
            this.timeout = timeout;
        }
        then(resolve, reject) {
            setTimeout{
                () => resolve('resolve'),
                this.timeout
            };
        }
    }
  • Async函數任何一個await返回reject,那麼就會致使整個Async的中斷執行。對象

    promise.all(),只有當它內部全部的子promise所有reslove時,整個promise纔會resolve,只要有一個reject,那麼整個promise.all就會reject,aysnc一樣的原理。

注意事項

  • 儘可能使用try...catch代碼塊,由於一旦用到了Async,顯然這個場景確定是有多個不方便操做的,這個時候爲了防止中間出錯,最好使用一個try...catch 的代碼塊,而後在catch代碼塊的內部加上咱們的一些備用數據。

  • 非繼發的await同時執行,繼發就是一個接一個也就是前面一個函數的輸出是後面一個函數的輸入,相似於函數式編程裏面的compose。 對於繼發的咱們沒有辦法只能等待前面的操做完再去執行後續操做。

    function resolveAfter2Seconds(value){
        return new Promise(resolve => {
          setTimeout(() => {
                resolve(value);
          },2000);
        });
    };
    
    const async = async function(){
        const value1 = await resolveAfter2Seconds(1);
        const value2 = await resolveAfter2Seconds(2);
        console.log(value1);
        console.log(value2);
    };
    async().then(res => {})
    // 4s 後輸出
       1
       2

    怎麼樣才能讓二者同步執行,能夠有兩種辦法。 第一種,使用Promise.all()將它封裝起來:

    function resolveAfter2Seconds(value){
        return new Promise(resolve => {
            setTimeout(() => {
                resolve(value);
            },2000);
        });
    }
    
    const async = async function() {
        const [value1,value2] = await Promise.all([resolveAfter2Seconds(1), resolveAfter2Seconds(2)])
        console.log(value1);
        console.log(value2);
    };
    async().then(res => {});
    // 2s後輸出
       1
       2

    第二種,先執行再await,也就是把異步的一個操做賦值給一個變量:

    function resolveAfter2Seconds(value){
        return new Promise(resolve => {
            setTimeout(() => {
                resolve(value);
            },2000);
        });
    }
    
    const async = async function() {
        const vpromise1 = resolveAfter2Seconds(1);
        const vpromise2 = resolveAfter2Seconds(2);
        const value1 = await vpromise1;
        const value2 = await vpromise2;
        console.log(value1);
        console.log(value2);
    }
    async().then(res => {});
    // 2s 後輸出
       1
       2
相關文章
相關標籤/搜索