iterators & generators-《understanding ECMAScipt6》讀書筆記8
前言
果然不能立flag,上次文章都寫完了,可是hexo出了點小問題,再加上正好回家,所以延後了幾天。
發現之前一直提到 迭代器 和 生成器的字眼。其實一直沒有講這方面的東東。iterators 在es6中應用的還是挺廣的,set,map,array,string都有這樣的入口,generators是es7中async的基礎。個人認為還是挺重要的。
iterators
很多語言都有iterators的概念。
在ES6中:
for-of迴圈基於iterators
...(擴散操作符)基於iterators
甚至非同步程式也用到iterators
為什麼需要iterators
迴圈存在的問題
需要多個變數去標記它,通用的比如i,len;
(其實這點我個人還不是很能理解)
iterators是什麼
iterators是一個擁有next()方法的物件,每次呼叫next()方法,返回一個下面的結構
{
done: false, //表示是否到達迴圈的終點
value: //該項的值
}
ES6中內建的iterators
集合物件
ES6 有三個型別的集合物件
- Arrays
- Maps
- Sets
他們都有以下的方法
- entries(),返回一個[key,value]的iterators
- Arrays返回的key為數字序號
- Sets,返回的key和value一樣的值
- Maps,返回的key為正常的key
- keys(),返回key的iterators
- 跟entries()中返回key是一樣的
- values(),返回一個values的iterators
- 跟entries()中返回value是一樣的
如果不指定迭代器方法的話,
Arrays和Sets呼叫的是values(),Maps呼叫的是entries()
判斷一個物件是不是迭代器 typeoof Object[Symbol.iterator] === 'function'
String迭代器
ES5中string存在效率低,無法識別雙位元組字元的情況。
ES6中解決了無法識別雙位元組字元的bug
NodeList迭代器
在ES5 中DOM的Nodelist和arrays區別很容易讓人困惑
ES6為DOM的Nodelist也增加了一個預設的迭代器,同陣列一樣,所以也可以使用for-of去迴圈
...操作符
...操作符是從迭代器中讀取資料並依次插入的
generators
什麼是generators
- generators是一個返回值是iterators的函式
- generators在function關鍵字後有號並且內部有yield關鍵字,號不一定要緊跟在function關鍵字後面
- 生成器執行時會在每次yield後停止執行,注:yield關鍵字只能存在於generators內部
- 書寫在物件內部的方法
let o1 = {
createIterator:function*(){
}
}
let o2 = {
*createIterator(){
}
}
//這兩種都可以
generator 傳參
往next()內傳參的話,會替換掉上次yield的返回值。
function *createIterator(){
let first = yield 1;
let second = yield first + 2;
yield second + 3;
}
let iterator = createIterator();
iterator.next() //{value:1,done:false}
iterator.next(4) //{value:6,done:false}
iterator.next(5)//{value:8,done:true}
generator 拋異常
iterator.throw()
- 在預計丟擲異常的時候,可以用try..catch捕獲
- 如果異常被捕獲,則throw()相當於next()返回的結果
- 如果generator內有return ,則return 後面的程式碼均不會執行
generator內可巢狀generator
非同步任務執行
利用generator的特性執行多個非同步任務,後續可以用Promise()進行改造
普通任務
該任務不需要利用上一步任務的返回值。
function run (tasks){
let task = tasks();
let result = task.next();
function step (){
if(!result.done){
result = task.next();
step();
}
}
step();
}
run(function * (){
console.log(1);
yield;
console.log(2);
yield;
console.log(3);
})
帶資料的任務
其實只變動了一處,將資料放在next()函式內部
function run (tasks){
let task = tasks();
let result = task.next();
function step (){
if(!result.done){
result = task.next(result.value);
step();
}
}
step();
}
非同步執行任務
如果result.value是一個函式
//假想的函式
function readFile(filename){
return function(cb){
fs.readFile(filename,cb);
};
}
function run (tasks){
let task = tasks();
let result = task.next();
function step(){
if(!result.done){
if(typeof result.value === 'function'){
result.value(function(err,data){
if(err){
task.throw(err);
}else{
task.next(data);
step();
}
})
}
}
}
step();
}
從上文程式碼中可以看的出來缺點:
- 必須要求函式為err優先
- 兩個函式的引數傳遞依賴於next()
相關文章
- MySQL 8.0 Reference Manual(讀書筆記59節--Understanding the Query Execution Plan(2))MySql筆記
- MySQL 8.0 Reference Manual(讀書筆記58節--Understanding the Query Execution Plan(1))MySql筆記
- 讀書筆記...筆記
- 讀書筆記筆記
- 《讀書與做人》讀書筆記筆記
- Cucumber讀書筆記筆記
- 散文讀書筆記筆記
- HTTP 讀書筆記HTTP筆記
- CoreJava讀書筆記-------Java筆記
- flask讀書筆記Flask筆記
- Vue讀書筆記Vue筆記
- MONGODB 讀書筆記MongoDB筆記
- Qt讀書筆記QT筆記
- Node讀書筆記筆記
- SAP讀書筆記筆記
- YII讀書筆記筆記
- iptables 讀書筆記筆記
- Makefile 讀書筆記筆記
- mysql讀書筆記MySql筆記
- 鎖讀書筆記筆記
- dataguard讀書筆記筆記
- 讀書筆記3筆記
- 讀書筆記2筆記
- postgres 讀書筆記筆記
- 閱讀筆記8筆記
- Iterators模式探討(筆記心得體會)模式筆記
- 《重構》讀書筆記筆記
- webpackDemo讀書筆記Web筆記
- PMBook讀書筆記(一)筆記
- Effective Java 讀書筆記Java筆記
- js高程讀書筆記JS筆記
- “Docker Practice”讀書筆記Docker筆記
- FPGA讀書筆記5FPGA筆記
- FPGA讀書筆記3FPGA筆記
- FPGA讀書筆記4FPGA筆記
- FPGA讀書筆記2FPGA筆記
- FPGA讀書筆記1FPGA筆記
- 《精通JavaScript》讀書筆記JavaScript筆記