【JavaScript】Generator函数

Generator函数是ES6引入的异步编程解决方案,它充当状态机,通过yield表达式分段执行。next方法控制执行流程,可以接受参数传递上一次yield的结果。在异步应用中,Generator结合Promise或async/await能优雅地处理异步操作,提高代码可读性和组织性。
摘要由CSDN通过智能技术生成

一、简介

Generator 函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同。

Generator 函数有多种理解角度。语法上,首先可以把它理解成,Generator 函数是一个状态机,封装了多个内部状态。

执行 Generator 函数会返回一个遍历器对象,也就是说,Generator 函数除了状态机,还是一个遍历器对象生成函数。返回的遍历器对象,可以依次遍历 Generator 函数内部的每一个状态。

二、基本用法

function * foo(x, y) { ··· }
function *foo(x, y) { ··· }
function* foo(x, y) { ··· }
function*foo(x, y) { ··· }

由于 Generator 函数仍然是普通函数,所以一般的写法是上面的第三种,即星号紧跟在 function 关键字后面。本书也采用这种写法。

该函数并不执行,返回的也不是函数运行结果,而是一个指向内部状态的指针对象。

function* helloWorldGenerator() {
  yield 'hello';
  yield 'world';
  return 'ending';
}


var hw = helloWorldGenerator();
console.log(hw);
console.log(hw.next());
console.log(hw.next());
console.log(hw.next());
console.log(hw.next());

在这里插入图片描述
helloWorldGenerator返回的是一个指针对象,可以调用 next 方法,内部指针就从函数头部或上一次停下来的地方开始执行,直到遇到下一个 yield 表达式(或 return 语句)为止。

换言之,Generator 函数是分段执行的, yield 表达式是暂停执行的标记,而 next 方法可以恢复执行。

三、next传参

yield表达式本身没有返回值,或者说总是返回 undefined 。
看一个例子:

function* add(x, y){
    let z = yield x + y;
    console.log('上一个yield的结果z是:', z);
    return z + 1;
}
const f = add(1, 2);
console.log(f.next());
console.log(f.next());
console.log(f.next());

在这里插入图片描述
可以看到,使用z来接收yield(x, y)的结果,发现是undefine。

next 方法可以带一个参数,该参数就会被当作上一个 yield 表达式的返回值
我们使用next带参数解决上面undefine问题。

function* add(x, y){
    let z = yield x + y;
    console.log('上一个yield的结果z是:', z);
    return z + 1;
}
const f = add(1, 2);
let z = f.next();
console.log(z);
console.log(f.next(z.value));
console.log(f.next());

在这里插入图片描述

四、Generator函数异步应用

ES6 诞生以前,异步编程的方法,大概有下面四种。

  1. 回调函数
  2. 事件监听
  3. 发布/订阅
  4. Promise 对象

Generator 函数将 JavaScript 异步编程带入了一个全新的阶段。

var fetch = require('node-fetch');


function* gen(){
  var url = 'https://api.github.com/users/github';
  var result = yield fetch(url);
  console.log(result.bio);
}

var g = gen();
var result = g.next();

//result.value是一个promise实例
result.value.then(function(data){
  return data.json();
}).then(function(data){
  //继续执行generator函数,传入上次结果data
  g.next(data);
});

而es2017提出的async函数则是 Generator 函数的语法糖,使用async配合await使得异步操作变得更加方便。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小绵杨Yancy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值