【前端】ES9:异步遍历器
文章目录
- 1 同步遍历器的问题
- 2 异步遍历器生成函数
- 3 for await of
- 4 案例改造
- 5 nodejs用法
1 同步遍历器的问题
function* fn() {
yield 1111
yield 2222
}
const syncI = fn();
console.log(syncI.next())
console.log(syncI.next())
console.log(syncI.next())
function* fn() {
yield new Promise(resolve=>resolve("1111"))
yield new Promise(resolve=>resolve("2222"))
}
const syncI = fn();
syncI.next().value.then(res=>{console.log(res)})
syncI.next().value.then(res=>{console.log(res)})
value
属性的返回值是一个Promise对象,用来放置异步操作。但是这样写很麻烦,不太符合直觉,语义也比较绕。
2 异步遍历器生成函数
Generator函数返回一个同步遍历器,异步Generator函数的作用,是返回一个异步遍历器对象。在语法上,异步Generator函数就是async函数与Generator函数的结合。
async function* fn() {
yield new Promise(resolve=>resolve("1111"))
yield new Promise(resolve=>resolve("2222"))
}
const asyncI = fn();
asyncI.next().then(res=>{
console.log(res)
return asyncI.next()
}).then(res=>{
console.log(res)
return asyncI.next()
}).then(res=>{
console.log(res)
})
3 for await of
for...of
循环用于遍历同步的Iterator接口。新引入的for await...of
循环,则是用于遍历异步的Iterator接口。
function ajax(data){
return new Promise(resolve=>{
resolve(data)
})
}
// 异步生成器
async function *gen(){
yield ajax(111)
yield ajax(222)
}
let g = gen() // g就是一个异步遍历器
async function test(){
let list = [g.next(), g.next(), g.next()]
for await(let i of list){
console.log(i)
}
}
test();
4 案例改造
- 同步遍历器:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
function timer(t){
return new Promise(resolve=>{
setTimeout(()=>{
resolve("data-" + t)
}, t)
})
}
async function test(){
let arr = [timer(1000), timer(2000), timer(3000)]
for(let item of arr){
console.log("start-", Date.now())
console.log(await item) // 同时并发,一秒后返回1000,再一秒后返回2000,再一秒后返回3000
console.log("end-", Date.now())
}
}
test()
</script>
</body>
</html>
- 异步遍历器:
function timer(t) {
return new Promise(resolve => {
setTimeout(() => {
resolve(t)
}, t)
})
}
async function* gen() {
yield timer(1000) // 任务1
yield timer(2000) // 任务2
yield timer(3000) // 任务3
}
async function test(){
let g = gen() // 异步生成器生成异步遍历器
let arr = [g.next(), g.next(), g.next()] // 异步遍历器生成的对象
for await(let item of arr){ // 等第一个g.next()有结果之后,执行代码块,卡住,等第二个g.next()有结果之后,执行代码块...
console.log("start-", Date.now())
console.log(item)
console.log("end-", Date.now()) // start和end同一时间执行
}
}
test();
5 nodejs用法
// 传统写法
function main(inputFilePath) {
const readStream = fs.createReadStream(
inputFilePath,
{ encoding: 'utf8', highWaterMark: 1024 }
);
readStream.on('data', (chunk) => {
console.log('>>> '+chunk);
});
readStream.on('end', () => {
console.log('### DONE ###');
});
}
// 异步遍历器写法
async function main(inputFilePath) {
const readStream = fs.createReadStream(
inputFilePath,
{ encoding: 'utf8', highWaterMark: 1024 }
);
for await (const chunk of readStream) {
console.log('>>> '+chunk);
}
console.log('### DONE ###');
}