TypeScript入门教程 之 生成器函数

TypeScript入门教程 之 生成器函数

 

生成器函数

function *是用于创建生成器函数的语法。调用generator函数将返回一个generator对象。发电机对象如下刚刚所述迭代器接口(即nextreturnthrow函数)。

生成器功能背后有两个主要动机:

 

延迟迭代器

生成器函数可用于创建延迟迭代器,例如,以下函数根据需要返回无限的整数列表:

function* infiniteSequence() {
    var i = 0;
    while(true) {
        yield i++;
    }
}

var iterator = infiniteSequence();
while (true) {
    console.log(iterator.next()); // { value: xxxx, done: false } forever and ever
}

 

当然,如果迭代器确实结束了,您将得到{ done: true }如下所示的结果:

function* idMaker(){
  let index = 0;
  while(index < 3)
    yield index++;
}

let gen = idMaker();

console.log(gen.next()); // { value: 0, done: false }
console.log(gen.next()); // { value: 1, done: false }
console.log(gen.next()); // { value: 2, done: false }
console.log(gen.next()); // { done: true }

 

外部控制执行

这是发电机真正令人兴奋的部分。它本质上允许函数暂停其执行,并将其余函数执行的控制权(命运)传递给调用者。

生成器函数在调用时不会执行。它只是创建一个生成器对象。考虑以下示例以及示例执行:

function* generator(){
    console.log('Execution started');
    yield 0;
    console.log('Execution resumed');
    yield 1;
    console.log('Execution resumed');
}

var iterator = generator();
console.log('Starting iteration'); // This will execute before anything in the generator function body executes
console.log(iterator.next()); // { value: 0, done: false }
console.log(iterator.next()); // { value: 1, done: false }
console.log(iterator.next()); // { value: undefined, done: true }

 

如果运行此命令,将得到以下输出:

$ node outside.js
Starting iteration
Execution started
{ value: 0, done: false }
Execution resumed
{ value: 1, done: false }
Execution resumed
{ value: undefined, done: true }

 

  • 该函数仅next在生成器对象上被调用一次才开始执行。
  • 一旦遇到语句,该函数就会暂停yield
  • 该函数在被调用时恢复next

因此,基本上生成器功能的执行可由生成器对象控制。

 

我们使用生成器进行通信主要是一种方法,其中生成器返回迭代器的值。JavaScript生成器的一个极其强大的功能是它们允许双向通信(带有警告)。

  • 您可以使用以下方法控制yield表达式的结果值iterator.next(valueToInject)
  • 您可以yield使用以下方式在表达式的位置抛出异常iterator.throw(error)

以下示例演示iterator.next(valueToInject)

function* generator() {
    const bar = yield 'foo'; // bar may be *any* type
    console.log(bar); // bar!
}

const iterator = generator();
// Start execution till we get first yield value
const foo = iterator.next();
console.log(foo.value); // foo
// Resume execution injecting bar
const nextThing = iterator.next('bar');

 

由于yield返回传递给迭代nextnext函数的参数,并且所有迭代器的函数都接受任何类型的参数,因此TypeScript将始终将any类型分配给yield运算符的结果(bar如上)。

您可以自行将结果强制为所需的类型,并确保仅将该类型的值传递给下一个类型(例如,通过搭建一个额外的要求next您的类型强制层)。如果强类型对于您可能希望完全避免双向通信,以及完全依赖它的软件包(例如redux-saga)。

以下示例演示iterator.throw(error)

function* generator() {
    try {
        yield 'foo';
    }
    catch(err) {
        console.log(err.message); // bar!
    }
}

var iterator = generator();
// Start execution till we get first yield value
var foo = iterator.next();
console.log(foo.value); // foo
// Resume execution throwing an exception 'bar'
var nextThing = iterator.throw(new Error('bar'));

 

因此,这里是摘要:

  • yield 允许生成器功能暂停其通信并将控制权传递给外部系统
  • 外部系统可以将值推入生成器功能主体
  • 外部系统可以在生成器函数体中引发异常

这有什么用?跳转到下一部分异步/等待并查找。

 

翻译来源:https://gitee.com/yunwisdoms/typescript-book/blob/master/docs/generators.md

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值