1、異步操作的同步化表達
Generator函數的暫停執行的效果,意味着可以把異步操作寫在yield語句里面,等到調用next方法時再往后執行。這實際上等同於不需要寫回調函數了,因為異步操作的后續操作可以放在yield語句下面,反正要等到調用next方法時再執行。所以,Generator函數的一個重要實際意義就是用來處理異步操作,改寫回調函數。
function* loadUI() { showLoadingScreen(); yield loadUIDataAsynchronously(); hideLoadingScreen(); } var loader = loadUI(); // 加載UI loader.next() // 卸載UI loader.next()
2、控制流管理
如果有一個多步操作非常耗時,采用回調函數,可能會寫成下面這樣。
step1(function (value1) { step2(value1, function(value2) { step3(value2, function(value3) { step4(value3, function(value4) { // Do something with value4 }); }); }); });
采用Promise改寫上面的代碼。
Promise.resolve(step1) .then(step2) .then(step3) .then(step4) .then(function (value4) { // Do something with value4 }, function (error) { // Handle any error from step1 through step4 }) .done();
上面代碼已經把回調函數,改成了直線執行的形式,但是加入了大量Promise的語法。Generator函數可以進一步改善代碼運行流程。
function* longRunningTask(value1) { try { var value2 = yield step1(value1); var value3 = yield step2(value2); var value4 = yield step3(value3); var value5 = yield step4(value4); // Do something with value4 } catch (e) { // Handle any error from step1 through step4 } }
3、部署Iterator接口
利用Generator函數,可以在任意對象上部署Iterator接口。
function* iterEntries(obj) { let keys = Object.keys(obj); for (let i=0; i < keys.length; i++) { let key = keys[i]; yield [key, obj[key]]; } } let myObj = { foo: 3, bar: 7 }; for (let [key, value] of iterEntries(myObj)) { console.log(key, value); } // foo 3 // bar 7
4、作為數據結構
Generator可以看作是數據結構,更確切地說,可以看作是一個數組結構,因為Generator函數可以返回一系列的值,這意味着它可以對任意表達式,提供類似數組的接口。
來自http://es6.ruanyifeng.com/#docs/generator#應用
