generator函數
其實從我開始接觸es6中的異步函數就是一直在用async await(這是es7的),是以generator基本沒用過,不過作為曾經的異步解決方案還是用必要了解一下。
generator函數的特點:
1、generator函數又名生成器函數,與普通函數不同,普通函數一旦調用就會執行完,但generator函數中間可以暫停,執行一會歇一會。
2、函數聲明時帶上 * ,如 function *go(){}。函數内部使用 yield 關鍵字實作暫停。
3、generator函數函數執行并不會有什麼效果,而是傳回一個疊代器對象,之後調用疊代器的 next 方法會傳回一個值對象。
舉例說明:
generator函數大概過程圖
代碼
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')
參考文章 參考文章