文章目录
- 1 同步遍历器的问题
- 2 异步遍历器生成函数
- 3 for await of
- 4 案例改造
- 5 nodejs用法
1 同步遍历器的问题
function* fn() {yield 1111yield 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,再一秒后返回3000console.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) // 任务1yield timer(2000) // 任务2yield 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 ###');
}