异步迭代器(async Iterator)
- 同步迭代器
- 异步迭代器
- for await…of
- 异步生成器函数
- yield*语句
1.同步迭代器
- 一般的迭代器生成函数在被调用后会返回一个迭代器对象,能够去调用迭代器上的next办法
-
next办法一旦执行,就必须同步地失去一个状态对象,{value,done}
//迭代器生成函数 function makeIterator(arr) { var nextIndex = 0; return { next() { return nextIndex < arr.length ? { value: arr[nextIndex++], done: false } : { value: undefined, done: true } } } } //调用并遍历 const arr = [1] let iter = makeIterator(arr) console.log(iter.next()) //{value: 1, done: false} console.log(iter.next());//{value: undefined, done: true}
2.异步迭代器
让next返回的value是一个Promise对象,用then链式解决
//迭代器生成函数
function makeIterator(arr) {
var nextIndex = 0;
let delay = 4000
return {
next() {
let res = nextIndex < arr.length ?
{
value: new Promise(resolve => setTimeout(() => resolve(arr[nextIndex++]), delay -= 1000)),
done: false
}
: { value: undefined, done: true }
return res
}
}
}
//调用并遍历
const arr = [1, 2]
let iter = makeIterator(arr)
iter.next().value.then(val => console.log(val)) //1
iter.next().value.then(val => console.log(val));//2
iter.next().value.then(val => console.log(val));//undefined
这种办法只是让value异步执行,done的值并不是异步产生的,并且执行了流程不清晰,语义比拟绕
next间接返回一个Promise,用then的链式解决异步
//迭代器生成函数
function asyncIterator(arr) {
var nextIndex = 0
return {
[Symbol.asyncIterator]() {
return {
next() {
if (nextIndex < arr.length) {
return new Promise(resolve => {
setTimeout(() => resolve({ value: arr[nextIndex++], done: false }), 1000)
})
} else {
return { value: undefined, done: true }
}
}
}
}
}
}
//链式执行
const asyncIterable = asyncIterator([1, 2])
const asyncIter = asyncIterable[Symbol.asyncIterator]()
asyncIter
.next()
.then(val1 => {
console.log(val1);
return asyncIter.next()
})
.then(val2 => {
console.log(val2);
return asyncIter.next()
})
.then(val3 => {
console.log(val3);
})
//{value: 1, done: false}
//{value: 2, done: false}
//{value: undefined, done: true}
既然asyncIter返回的是一个Promise,那么执行能够用async改写,能失去统一的后果
async function runner() {
const asyncIterable = asyncIterator([1, 2])
const asyncIter = asyncIterable[Symbol.asyncIterator]()
let val1 = await asyncIter.next()
console.log(val1);
console.log(await asyncIter.next());
console.log(await asyncIter.next());
}
3 for await…of
依据下面的迭代器生成函数,Symbol.asyncIterator是一个异步迭代器的接口,返回一个迭代器对象,能够用for await…of去遍历这个接口
async function runner() {
for await (const i of asyncIterator([1, 2])) {
console.log(i);
}
}
runner()
//1
//2
- asyncIterator([1, 2])返回一个
对象
,这个对象领有异步迭代器接口,能返回一个异步迭代器对象 - 这个对象的异步迭代器的next办法被for…of循环主动调用会失去一个
Promise 对象
- await用来解决这个 Promise 对象,在resolve之后把失去的值i
传入
for…of的循环体
遍历出错会终止for await…of,并报错
能够将for await..of放在try中,用catch捕捉谬误
4.异步生成器函数
同步的生成器函数会生成一个同步迭代器,那么异步生成器则生成异步迭代器
作用
Generator 函数解决同步操作和异步操作时,可能应用同一套接口
特点
异步生成器函数就是async和Generator的联合
function promise(data, delay) {
return new Promise(resolve => {
setTimeout(() => {
resolve(data)
}, delay)
})
}
function printHello() {
return promise("Hello", 1000)
}
function printWorld() {
return promise("World", 1000)
}
async function* gene() {
yield printHello()
yield printWorld()
}
let iter = gene()
iter.next()
.then(val => { console.log(val); })//{value:"Hello",done:false}
- 异步的生成器函数返回一个迭代器对象,调用next办法,返回的是一个
Promise
,用then能取到状态对象 - 同步的生成器函数返回一个迭代器对象,调用next办法,间接返回
状态对象
,状态对象中的value是一个Promise -
应用for await…of能够异步的遍历同步迭代器,然而只有value是异步的,done的生成依然是同步的
async function runner() { for await (const i of iter) { console.log(i); } } runner()
不论Generator函数前是否有async都会别离提早1000ms打印Hello与World
await 和 yield能够同时呈现在异步Generator函数中
async function* readLines(path) {
let file = await fileOpen(path);
try {
while (!file.EOF) {
yield await file.readLine();
}
} finally {
await file.close();
}
}
await前面的操作返回一个Promise对象,将内部操作产生的值输出函数外部
yield命令会返回一个Promise,作为每个next暂停的地位,将函数外部的值输入
- async函数和异步Generator函数都是对异步操作的封装
- async函数自带执行器
- 异步Generator函数能够用for await…of去遍历
函数就能够分为四类
- 一般函数
- async函数
- Generator函数
- 异步Generator函数
5. yield* 语句
yield* 后能够跟一个Generator函数,将其语句开展到异步生成器内
function* gene1() {
yield 'a'
yield 'b'
console.log(0);
}
async function* gene2() {
yield* gene1()
yield 'c';
}
async function runner() {
for await (const i of gene2()) {
console.log(i);
}
}
runner()
//"a"
//"b"
//0
//"c"