天天看點

generator函數與async函數generator函數async函數

generator函數

其實從我開始接觸es6中的異步函數就是一直在用async await(這是es7的),是以generator基本沒用過,不過作為曾經的異步解決方案還是用必要了解一下。

generator函數的特點:

1、generator函數又名生成器函數,與普通函數不同,普通函數一旦調用就會執行完,但generator函數中間可以暫停,執行一會歇一會。

2、函數聲明時帶上 * ,如 function *go(){}。函數内部使用 yield 關鍵字實作暫停。

3、generator函數函數執行并不會有什麼效果,而是傳回一個疊代器對象,之後調用疊代器的 next 方法會傳回一個值對象。

舉例說明:

generator函數大概過程圖

generator函數與async函數generator函數async函數

代碼

function *go(a){
    console.log(1);
    // yield語句隻是個辨別符,并沒有傳回值
    // yield左邊等于等于next()傳來的參數值,沒傳參則為undefined。yield右邊的是next()的傳回值。
    let b = yield a;
    console.log(2);
    let c = yield b;
    console.log(3);
    return c;
}

let iterator = go('aaa');
let r1 = iterator.next();   //第一次next不用傳參,沒有意義
console.log(r1);    //{ value: 'aaa', done: false }
let r2 = iterator.next('bbb');
console.log(r2)     //{ value: 'bbb', done: false }
let r3 = iterator.next();
console.log(r3)     //{ value: undefined, done: true }
           

注意:

  • yield語句隻是個辨別符,并沒有傳回值。
  • yield左邊等于等于next()傳來的參數值,沒傳參則為undefined。yield右邊的是next()的傳回值。
  • next()傳回的對象中done屬性值代表目前疊代是否完成

async函數

async函數顧名思義就是異步函數,可以了解為是generator的文法糖。現在應用中異步任務更多使用基于promise與async函數的解決方案。

async函數的幾個特點

1、使用async關鍵字聲明函數(如:async function fn(){}).

2、async函數預設傳回一個已解決的promise對象,如果手動return其他值,函數會自動return Promise.resolve(其他值)

await

async await是天生一對,async函數中沒有出現await那就跟普通函數沒什麼差別,而await也隻能在async函數中使用。

await顧名思義“等待”,await指令後是一個promise對象,如果不是,會被轉成一個resolve的promise對象。如果await後面的promise狀态是reject的話會抛出異常,是以可以将await語句寫在try catch裡。

當async函數執行的時候,一旦遇到await就會先傳回,等到異步操作完成,再接着執行函數體内後面的語句,是以調用async函數雖然有等待, 但是并不會導緻阻塞, 因為他内部的所有阻塞都封裝在promise對象中異步執行.。

與promise方式的簡單對比

function promiseFn(){
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('hello');
        }, 2000)
    })
}

//promise方式
promiseFn().then(re => {
    console.log(re);
})

//async await方式
async function fn(){
    let re = await promiseFn();
    console.log(re);
}
fn();

console.log('world')
           

參考文章    參考文章

繼續閱讀