生活随笔
收集整理的這篇文章主要介紹了
【co】ES6-20/21 iterator与generator
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
ES6-20 iterator與generator
ES6-21 async與await、ES6的模塊化
try catch不能捕獲異步異常
try {setTimeout(() => {console
.log(a
)})
} catch (e
) {console
.log(e
)
}
iterator
內部迭代器:系統定義好的迭代器接口(如數組Symbol.iterator)
外部迭代器:手動部署(可以給obj定義外部迭代器)
對于遍歷器對象來說,done: false和value: undefined屬性都是可以省略的
內部迭代器:
- 除了next之外還可以增加return(){},在for…of循環中凡是使用break或者throw new Errow()來終止循環的,會走return
let obj
= {a
: 1,b
: 2,c
: 3,[Symbol
.iterator
]() {let nextIndex
= 0let map
= new Map()for (let [key
, value
] of Object
.entries(this)) {map
.set(key
, value
)}let mapEntries
= [...map
.entries()],len
= mapEntries
.length
return {next() {return nextIndex
< len
?{ value
: mapEntries
[nextIndex
++], done
: false } :{ value
: undefined, done
: true }}}}
}
for (let i
of obj
) {console
.log(i
)
}
默認調用iterator接口
- ...
- for...of
- Array.from()
- map\set
- Promise.all() Promise.race()
- yield
generator
- 生成器
- 用于返回迭代器對象
- yield只能出現在生成器中
- yield執行的返回值是undefined(并不產生值)
- 結合yield使用,能結合next拿到
- yield暫停代碼運行,有記憶功能
- return代碼終止
- 不調用next時,不會運行test內的代碼
function * test(){yield 'a'console
.log('第二次調用next時才打印')yield 'b'yield 'c'return 'd'}
let iter
= test()
console
.log(iter
.next())
console
.log(iter
.next())
console
.log(iter
.next())
console
.log(iter
.next())
return
- 終止迭代,done為true,value取決于是否有返回值
- 內部return
function* test() {yield 1;return;yield 2;
}
let it
= test()
console
.log(it
.next())
console
.log(it
.next())
console
.log(it
.next())
function* test() {yield 1;return 10;yield 2;
}
let it
= test()
console
.log(it
.next())
console
.log(it
.next())
function* test() {yield 1;yield 2;
}
let it
= test()
console
.log(it
.next())
console
.log(it
.return(10))
console
.log(it
.next())
throw
- 必須要在第一次調用next之后調用throw,才能被捕獲(捕獲區間在try里的第一個yield之后)
- throw的表達式本身要是正確的
function* test() {try {yield 1;yield 2;} catch (e
) {console
.log('生成器內部異常', e
)}
}
let it
= test()
console
.log(it
.next())
console
.log(it
.throw(1))
console
.log(it
.next())
function* test() {try {yield 1;yield 2;} catch (e
) {console
.log('生成器內部異常', e
)}
}
let it
= test()
console
.log(it
.next())
console
.log(it
.throw(1))
console
.log(it
.throw(2))
function* test() {try {yield 1;yield 2;} catch (e
) {console
.log('生成器內部異常', e
)}yield 3;
}
let it
= test()
console
.log(it
.next())
console
.log(it
.throw(1))
const fs
= require('fs')
const util
= require('util')
const co
= require('co')
let readFile
= util
.promisify(fs
.readFile
)
function* read() {try {let val1
= yield readFile('firsttxt', 'utf-8')let val2
= yield readFile(val1
, 'utf-8')let val3
= yield readFile(val2
, 'utf-8')console
.log('inner', val3
)} catch (e
) {console
.log('異常捕獲', e
)}console
.log('正常執行')
}
let it
= read()
let promise
= co(it
)
promise
.then((val) => {console
.log(val
)
})
for…of循環
function* foo() {yield 1;yield 2;yield 3;yield 4;yield 5;return 6;
}for (let v
of foo()) {console
.log(v
);
}
實現斐波那契
function* fibonacci() {let [prev
, curr
] = [0, 1];for (;;) {yield curr
;[prev
, curr
] = [curr
, prev
+ curr
];}
}for (let n
of fibonacci()) {if (n
> 1000) break;console
.log(n
);
}
遍歷對象
const obj
= {a
: 1,b
: 2,c
: 3
}
function* test(obj) {for (let key
in obj
) {yield [key
, obj
[key
]]}
}
for (let [key
, val
] of test(obj
)) {console
.log(key
+ ':' + val
)
}
const obj
= {a
: 1,b
: 2,c
: 3,[Symbol
.iterator
]: test
}
function* test() {for (let key
in this) {yield [key
, this[key
]]}
}
for (let [key
, val
] of obj
) {console
.log(key
+ ':' + val
)
}
yield執行返回值
const fs
= require('fs')function promisifyAll(obj) {for (let [key
, fn
] of Object
.entries(obj
)) {if (typeof fn
=== 'function') {obj
[key
+ 'Async'] = promisify(fn
)}}
}
promisifyAll(fs
)
function promisify(func) {return function (...args) {return new Promise((resolve, reject) => {func(...args
, (err, data) => {if (err
) {reject(new Error(err
))} else {resolve(data
)}})})}
}
let readFile
= fs
.readFileAsync
function* read() {let val1
= yield readFile('first.txt', 'utf-8')let val2
= yield readFile(val1
, 'utf-8')let val3
= yield readFile(val2
, 'utf-8')console
.log('inner', val3
)}
let it
= read()
let { value
} = it
.next()
value
.then((val1) => {let { value
} = it
.next(val1
)value
.then((val2) => {let { value
} = it
.next(val2
)value
.then((val3) => {console
.log('val3', val3
)it
.next(val3
)})})
})
let it
= read()
function Co(it) {return new Promise((resolve, reject) => {let next = (data) => {let { value
, done
} = it
.next(data
)if (done
) {resolve(value
)} else {value
.then((val) => {next(val
)})}}next()})
}
let promise
= Co(it
)
promise
.then((val) => {console
.log(val
)
})
let co
= require('co')
let promise
= co(it
)
promise
.then((val) => {console
.log(val
)
})
yield*
- ES6 提供了yield*表達式,用來在一個 Generator 函數里面執行另一個 Generator 函數。
function* bar() {yield 'x';yield* foo();yield 'y';
}
function* bar() {yield 'x';yield 'a';yield 'b';yield 'y';
}
async await
- async替換*
- await替換yield
- async函數內無論寫return什么,返回值都是promise(隱式通過Promise.resolve()包裝了返回值)
const fs
= require('fs')
const util
= require('util')
const co
= require('co')
let readFile
= util
.promisify(fs
.readFile
)
async function read() {try {let val1
= await readFile('first.txt', 'utf-8')let val2
= await readFile(val1
, 'utf-8')let val3
= await readFile(val2
, 'utf-8')console
.log('inner', val3
)} catch (e
) {console
.log('異常捕獲', e
)}console
.log('正常執行')}
let promise
= read()
promise
.then((val) => {console
.log(val
)
})
const fs
= require('fs')
const util
= require('util')
const co
= require('co')
let readFile
= util
.promisify(fs
.readFile
)
async function read() {let val1
= await readFile('first.txt', 'utf-8')console
.log(a
)let val2
= await readFile(val1
, 'utf-8')let val3
= await readFile(val2
, 'utf-8')console
.log('inner', val3
)console
.log('正常執行')
}
let promise
= read()
promise
.then((val) => {console
.log(val
)
}).catch((e) => {console
.log('catch到異常', e
)
})
Promise.all
- 一個出錯,在then里都拿不到,會在catch里捕獲到第一個錯誤
const fs
= require('fs')
const util
= require('util')
let readFile
= util
.promisify(fs
.readFile
)
let f
= Promise
.all([readFile('first.txt', 'utf-8'),readFile('secondtxt', 'utf-8'),readFile('thirdtxt', 'utf-8'),
])
f
.then((val) => {console
.log('then', val
)
}).catch((err) => {console
.log('err', err
)
})
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎
總結
以上是生活随笔為你收集整理的【co】ES6-20/21 iterator与generator的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。