1. 程式人生 > >es6 generator函數

es6 generator函數

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函數