Javascript异步遍历器

遍历器是ES6新增的一个属性,用于遍历得到一个数据的值,调用next方法可以依次拿到一个对象{value, done}

function idMaker() {
	let index = 0;

	next() {
		return { value: index++, done: false }
	}
}
const it = idMaker();
it.next(); //{value: 0, done: false}
it.next(); //{value: 1, done: false}

上面代码中, it是一个遍历器,调用next方法就可以同步得到一个对象,默认是同步执行,如果是next是异步方法,会有什么结果呢,看下面的代码:

function idMaker() {
  let index = 0;

  return {
    next: function() {
      return new Promise(function (resolve, reject) {
        setTimeout(() => {
          resolve({ value: index++, done: false });
        }, 1000);
      });
    }
  };
}
const it = idMaker();
console.log(it.next()); // Promise

上面的代码中,next方法返回一个Promise对象,这违背了Iterator必须是异步的原则,是无法达到目的的,这个如何解决呢?

我们可以把异步操作包装成Thunk函数或者Promise对象,等待返回真正的值,done属性是同步产生的

function idMaker() {
  let index = 0;

  return {
    next: function() {
      return {
        value: new Promise(resolve => setTimeout(() => resolve(index++), 1000)),
        done: false
      };
    }
  };
}

const it = idMaker();

it.next().value.then(o => console.log(o)) // 0
it.next().value.then(o => console.log(o)) // 1
it.next().value.then(o => console.log(o)) // 2

上面的代码中,value的值是一个Promise对象,想要得到value的值,需要使用nextthen的写法,不过这样写起来比较麻烦

1 异步遍历的接口

异步遍历器的的语法是调用遍历器的next方法,返回一个promise对象,可以通过then方法拿到value值

asyncIterator
  .next()
  .then(
    ({ value, done }) => /* ... */
  );

对象的同步遍历器接口部署在Symbol.Iterator属性上面,而异步遍历器接口部署在Symbol.asyncIterator上,只要一个对象部署了异步遍历器,就需要对它进行异步遍历

创建一个异步遍历器:

const asyncIterable = createAsyncIterable(['a', 'b']);
const asyncIterator = asyncIterable[Symbol.asyncIterator]();

asyncIterator
.next()
.then(iterResult1 => {
  console.log(iterResult1); // { value: 'a', done: false }
  return asyncIterator.next();
})
.then(iterResult2 => {
  console.log(iterResult2); // { value: 'b', done: false }
  return asyncIterator.next();
})
.then(iterResult3 => {
  console.log(iterResult3); // { value: undefined, done: true }
});

2 for await … of

我们直到,for…of可以遍历同步遍历器,现在说的for await … of 是遍历异步遍历器的方法,下面是一个伪代码示例:

async function f() {
  for await (const x of createAsyncIterable(['a', 'b'])) {
    console.log(x);
  }
}
// a
// b

createAsyncIterator是一个异步遍历器接口对象,使用for…of的话,返回的是一个promise对象,使用await则可以处理这个promise对象,resolve之后,则会返给for…of循环

这个for await…of用于什么场景呢?下面举个例子,用于node环境中的stream接口

// 传统写法
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 ###');
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值