generator函式在工作中還沒有用到過,一直在使用async,最近在看async的原理,發現它只是generator的語法糖。
generator的基礎知識之前寫過文章介紹過(這裡主要討論一下怎麼使用generator函式來進行非同步程式設計。
先來看下面的**:
1執行結果:function*g()
6 const useg =g();
7useg.next();
8 useg.next();
分析:看下面的**:
1執行結果:function*g() , 3000)8}
9 console.log('g end')10}
11 const useg =g();
12 const first =useg.next();
13 first.value(() => useg.next());
分析:我們再來看一下實際的例子,使用generator函式封裝ajax:
1上面的**執行的是:先通過id取得使用者名稱,再通過使用者名稱取得家庭成員。只看第1行到第27行,步驟清晰,很像是同步的寫法。function*g()
12 xhr.send(null
);13
}14 const families = yield function
(callback) `, true);
17 xhr.responsetype = 'json';
19 xhr.onload = () =>
23 xhr.send(null
);24}25
console.log(families)
26 console.log('g end')27}
28 const useg =g();
29 const first =useg.next();
30first.value(
31 (name) =>
37 );
我們需要關注的是,第28行到第37行對generator函式的流程管理:
呼叫generator函式取得迭代器物件
呼叫next方法取得value屬性
呼叫value屬性的值,給它傳入**函式
在**函式中執行第2步,第3步
判斷此時函式已經執行完成
注意到這裡的12345步是可以用迭代來進行的,修改流程管理的**如下:
1可以看到,使用迭代來管理流程時完全沒有必要知道生成器的內部結構。而且這種方式也不管生成器中有多少個yield。function
run(g)
13//
開始迭代
14loop();15}
16 run(g);
有一點需要注意的是,使用這種發生來管理流程要求生成器中yield後面的表示式必須是乙個函式,且這個函式有唯一引數(**函式)
其實,我們需要的只是在非同步操作有了結果之後把執行權再交還給generator函式繼續執行。
問題是怎麼知道非同步操作有了結果?
**函式
promise
上面已經介紹過使用**函式來控制流程,它的限制是yield後面的表示式必須是乙個以**函式為引數的函式。
下面介紹使用promise來控制流程:
ajax函式返回promise
1view codefunction
ajax(url)
12 xhr.send(null
);13}14
)15 }
1可以看到:function*g()
8 const useg =g();
9useg.next().value.then(
10 (usernameresponse) =>useg.next(usernameresponse).value.then(
11 (familiesresponse) =>useg.next(familiesresponse)12)
13 );
yield後面必須是promise物件
流程控制中同樣可以使用迭代來執行
promise迭代版本的流程控制:
function對比之前的使用**函式來控制流程的**,你會發現和使用promise來控制流程的**如此的類似。run(g)
//開始迭代
loop();
}run(g);
使用promise來控制流程需要注意的是yield後面必須是乙個promise物件
對比使用**函式控制流程和使用promise物件來控制流程
總結:generator函式本身使得非同步操作看起來非常像同步操作,麻煩的是它的流程控制需要我們手動呼叫。(之後要討論的async就是對generator的進一步封裝,不用開發者總結來流程控制)
另外上面的例子為了簡化,都沒有做異常處理,實際開發中,異常處理還是很有必要的。
作成:2019-02-10
修改:2019-02-10 23:23:57 新增分類
參考:《es6標準入門》、《learning typescript》、《深入理解es6》
關於generator函式的理解與使用
關於generator函式的理解與使用 在js中普通function一但建立並呼叫後,直到return,是不會被打斷,而generator函式是es6提供的乙個關於非同步程式設計的解決方案,特點就是generator函式不會返回執行結果,而是便利函式內部的結果或者狀態,通過函式.next 一次次的輸...
Generator函式學習
例子1 const test function x const a test 1 console.log a.next 3 x 2 3 console.log a.next 11 22 3 2 11 3 console.log a.next 2 18 3 2 3 console.log a.next...
迭代函式 Generator函式的理解
一 基本用法 generator函式跟普通函式在寫法上的區別就是,多了乙個星號 並且只有在generator函式中才能使用yield 什麼是yield呢,他相當於generator函式執行的中途暫停點,比如下方有3個暫停點。而怎麼才能暫停後繼續走呢?那就得使用到next方法,next方法執行後會返回...