当前位置:  开发笔记 > 编程语言 > 正文

ES6异步发生器结果

如何解决《ES6异步发生器结果》经验,为你挑选了1个好方法。

ES6具有返回迭代器的生成器:

function* range(n) {
    for (let i = 0; i < n; ++i) {
        yield i;
    }
}

for (let x of range(10)) {
    console.log(x);
}

有一个异步函数的提议,它返回Promises:

async function f(x) {
    let y = await g(x);
    return y * y;
}

f(2).then(y => {
    console.log(y);
});

那么如果我将两者结合起来会发生什么,就像这样:

async function* ag(n) {
    for (let i = 0; i < n; ++i) {
         yield i;
    }
}

它返回了什么?是Promise>吗?Iterator>?别的什么?我该如何食用?我想应该有一个相应的for循环,什么会异步迭代它的结果,如:

for (await let x of ag(10)) {
    console.log(x);
}

在尝试访问下一个项目之前等待每个项目可用.



1> Tamas Hegedu..:
Promise>还是Iterator>

都不是.它仍未获得批准,但当前的实现还会返回其他内容.Kris Kowal 撰写了一篇关于异步生成器的文章,并参考了Jafar Husain的AsyncGenerator对ES7的提议.编辑:我们有tc39提案和babel支持!

让我们定义一些类型(简化):

interface Iterator {
  Iteration next();
}

type Iteration = { done: boolean, value: T }

我们正在寻找可以像这样使用的东西:

for (;;) {
    var iteration = await async_iterator.next();
    if (iteration.done) {
        return iteration.value;
    } else {
        console.log(iteration.value);
    }
}

An Iterator>生成同步迭代,其值为Promises.它可以像这样使用:

for (;;) {
    var iteration = iterator_promise.next();
    if (iteration.done) {
        return await iteration.value;
    } else {
        console.log(await iteration.value);
    }
}

A Promise>只是一个常规的同步迭代器,从未来开始:

var iterator = await promise_iterator;
for (;;) {
    var iteration = iterator.next();
    if (iteration.done) {
        return iteration.value;
    } else {
        console.log(iteration.value);
    }
}

所以既不合适Iterator>Promise>不合适.目前异步生成器返回AsyncIterators:

interface AsyncIterator {
  Promise> next();
}

这完全有道理.移动到迭代器的下一个元素是异步操作,这可以完全按照我们想要的方式使用.

如何使用异步生成器?

Babeljs.io已经编译了异步生成器.Babeljs.io/repl示例:

编辑:babeljs.io没有预设编译异步生成器,因为babel 6,babel-plugin-transform-regenerator支持{asyncGenerators:true}选项.

编辑:看看transform-async-generator-functionsbabel 6插件.

function delay(timeout, val) {
  return new Promise(resolve => setTimeout(resolve, timeout, val));
}

async function* asyncGenerator() {
  for (var i = 0; i < 5; i++) {
    await delay(500);
    yield i;
  }
}

async function forAwait(iter, fn) {
  for (;;) {
    let iteration = await iter.next();
    if (iteration.done) return iteration.value;
    await fn(iteration.value);
  }
}


async function main() {
  console.log('Started');
  await forAwait(asyncGenerator(), async item => {
    await delay(100);
    console.log(item);
  });
  console.log('End');
}

main();

有一个方便的for await循环用于异步迭代器的建议(在Async迭代中描述):

for await (let line of readLines(filePath)) {
    print(line);
}

更新:

不幸的是,async-await没有成为ECMAScript 2016的一部分.至少await提到了一个保留字以供将来使用.

更新:

相关提案:

https://tc39.github.io/ecmascript-asyncawait/

https://github.com/tc39/proposal-async-iteration

推荐阅读
mobiledu2402851203
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有