es6 generator函數
阿新 • • 發佈:2019-04-06
val 直接 普通 返回值 就是 gen 跳轉 對象屬性 訪問
es6 新增了Generator函數,一種異步編程的解決方案
回顧一下,es6 提供了新的遍歷方法,for of ,適用於各種數據集合,統一了遍歷操作,原生支持for of 集合的數據集合有。數組,字符串
一部分的類數組,map,set。而對象是不適合與 for of 遍歷的,因為原生沒有實現Iterator接口,而手動的為對象添加Iterator接口,我們之前使用
return next() 操作,而今天我們嘗試用Generator 函數去實現對像的Iterator接口,
// Generator 函數實現對象的 Iterator接口 // 定義一個簡單的對象 let obj = { a:‘12344444‘, b: ‘333444‘, c: ‘dddddd‘, d: ‘meiy‘ } // 在 for of 學習中我們知道,要想使用for of 遍歷 我們需要給對象實現Symbol.iterator接口 // Generator 函數的定義是function* ,每次調用Generator.next() 會執行函數內部的yeild obj[Symbol.iterator] = function* () { let keys =Object.keys(this) // Object.keys 得到的對象屬性集合可以直接使用for of for(let key of keys) { yield [key,this[key]] } } // 上面對象的Iterator接口已經定義完成下面我們使用for of 循環遍歷 for(let item of obj) { console.log(item) }
// 結果
[ ‘a‘, ‘12344444‘ ]
[ ‘b‘, ‘333444‘ ]
[ ‘c‘, ‘dddddd‘ ]
[ ‘d‘, ‘meiy‘ ]
定義後Genertation函數後,我們可以像調用普通函數一樣,使用()去調用,但是Generator函數直接調用是不會執行的,我們必須掉用
Generator函數next()使其執行,執行到第一個yeild ,放回一個對象{value:‘‘,done:false} ,如果對象已經執行完,則返回{value:‘‘,done:true},如果還繼續
掉用next()方法則返回{value:undefined,done:true},Generator 除了next()外,還有兩個操作,分別是throw(),return();(註,yeild 只能用於Generator內部)
// Generator 函數 next() return() throw() // 讓我們先定義一個簡單的Generator函數 function* gen() { console.log(‘開始了‘) yield 1 yield 2 yield 3 return 4 } // 當我們使用()去掉用時gen函數數,並不執行 let g = gen() // 不會輸出開始了 註,Generator 不能使用new 去實例,會報錯 console.log(g.next()) // 輸出 開始了 { value: 1, done: false } 執行到第一個yeild處 console.log(g.next()) //{ value: 2, done: false } console.log(g.next()) //{ value: 3, done: false } console.log(g.next()) //{ value: 4, done: true } //執行完 則done 放回ture // 如果沒有最後一個return ,放回值就是undefined //next() 函數可以傳入一個參數,作為上一個yeild 的返回值 function* fhz (x) { let y = yield x +1 let z = yield y + 12 return y+z } let zx = fhz(5); console.log(zx.next()) // 執行第一個 yeild 表達式,返回6 // 執行第二個yeild 表達式,第一個yeild並未傳值進去,則y時undefined //console.log(zx.next()) // undefined+12 =>> Nan console.log(zx.next(2)) // 14 console.log(zx.next(1)) // 3 // 上一步執行完,y = 2 這一步,傳入的是1 未yeild y+12的值,也是z的值,所有最終輸出3
Generation throw()方法
// Generator throw() function* throws() { try { yield 2 } catch (ex) { console.log(‘th‘+ex) } } let th = throws(); th.next() //只有調用了next Generator 內部才能執行 th.throw() //thundefined try { th.throw(‘我該‘) // 內部已經沒有catch 則訪問外部的catch } catch (err) { console.log(‘12‘,err) } function* jdd() { throw new Error(‘不多不少‘) yield 33; //前面拋出了 throw 這裏就不會再執行了 } let sj = jdd() try { sj.next() } catch (err) { console.log(err) } try { console.log(sj.next()) } catch (err) { console.log(err) }
Generation return 函數
// Generator return() function* fn () { yield 1 yield 2 yield 3 yield 4 return 67 } let f = fn() console.log(f.return()) // { value: undefined, done: true } 因為未傳入參數,返回的就是undefined console.log(f.return(123)) // { value: 123, done: true } rerutn 後函數就不執行了 // 但如果函數內部有try finally 則直接會跳轉到執行finally 內部 function* finna () { try { yield 1 yield 2 yield 3 } finally { yield 4 yield 5 } return 6 } let fina = finna() console.log(fina.next()) //{ value: 1, done: false } console.log(fina.return()) // 使用return,執行 執行yeild 4 console.log(fina.next()) //執行yeild 5 console.log(fina.next()) //執行,fina.return() console.log(fina.next()) //{ value: undefined, done: true }
es6 generator函數