Generator函数
概念
- Es6提供的解决异步编程的方案之一
- Generator函数是一个状态机,内部封装了不同状态的数据
- 用来生成遍历器对象
- 可暂停函数(惰性求值)
1.yield:暂停
2.next 启动
每次返回的是yield后的表达式结果
特点
1.function与函数名之间有一个*号
2.内部用yield表达式定义不同状态
3.generator函数返回的是指针对象 而不会执行函数内部逻辑
4.调用next方法函数内部逻辑开始执行,遇到yield表达式停止,返回{value:yield 后的表达式结果/undefind,done:}
5.再次调用next方法会从上一个yield处开始直到最后
6.yield语句返回结果通常为undefind,当调用next方法时传参内容会作为启动时yield语句的返回值
小试牛刀
function* myGenerator(){
console.log('hello word')
yield 'hello'
}
myGenerator()
//
我们定义了一个generator函数,当调用该函数时,却什么也没有执行 这是因为generator函数返回的是指针对象(参照Iterator) 而不会执行函数内部逻辑
既然返回值是指针对象,那么我们可以直接调用next()
function* myGenerator(){
console.log('hello word')
yield 'hello'
}
var t = myGenerator()
t.next()
//hello word
Generator执行生成指针对象,当调用指针对象next,开始执行函数逻辑,当遇到yield
语句后,当前函数会在yield处暂停,如果yield后面是个表达式则会被返回,如果是语句则会被执行,在返回{value:undifind}
function* myGenerator(){
console.log('hello word')
yield 'hello'
}
var t = myGenerator()
console.log(t.next())
//返回如下
hello word
{value: "hello", done: false}
//第二种
console.log('hello word')
yield console.log('test')
}
var t = myGenerator()
//返回如下
console.log(t.next())
hello word
test
{value: undefined, done: false}
//第三种
function* myGenerator(){
console.log('hello word')
yield console.log('test')
console.log('暂停后执行')
yield "generator"
}
var t = myGenerator()//指针对象
console.log(t.next())
console.log(t.next())
//返回如下
hello word
test
{value: undefined, done: false}
暂停后执行
{value: "generator", done: false}
done:false表示函数内部状态为执行完毕,当执行完毕时返回true
function* myGenerator(){
console.log('hello word')
yield console.log('test')
console.log('暂停后执行')
yield "generator"
return '返回的结果'
}
var t = myGenerator()
console.log(t.next())
console.log(t.next())
console.log(t.next())
//返回如下
hello word
{value: undefined, done: false}
暂停后执行
{value: ‘返回的结果’ done: true}
yield一般返回undefined
,我们可以在下一个next执行时传入参数,这个参数可作为yield的返回值
function* myGenerator(){
console.log('hello word')
let res = yield 'hello'
console.log(res)
yield "generator"
}
var t = myGenerator()
console.log(t.next())
console.log(t.next('返回值'))
//返回如下
hello word
{value: "hello", done: false}
返回值
{value: "generator", done: false}
示例
基于Generator的特性我们可以解决异步回调问题 如下先发送请求获取新闻,在根据新闻得到当前新闻的评论
function getNews(url){
$.get(url,function(data){
console.log(data)
let url = 'http://localhost:3000'+data.commentUrl;
})
}
function* sendXml(){
yield getNews('http://localhost:3000/news?id=2') //获取新闻
yield getNews(url) //获取评论
}
//获取遍历器对象
let SX = sendXml();
SX.next()//第一次调用next
第一次调用next时 指针指向第一个yield,进行请求发送操作获取新闻数据,我们在getNews中获取到新闻数据对应的评论url,因此此时请求已经发送成功
接下来我们要获取评论内容,因此我们又要进行next操作
function getNews(url){
$.get(url,function(data){
console.log(data)
let url = 'http://localhost:3000'+data.commentUrl;
})
}
function* sendXml(){
yield getNews('http://localhost:3000/news?id=2') //获取新闻
yield getNews(url) //获取评论
}
//获取遍历器对象
let SX = sendXml();
SX.next()//第一次调用next
SX.next()//第二次调用next
按理说第二次调用进行到第二个yield,此时进行评论获取操作,但是评论获取需要上一个请求得到的url,我们在外面调用next根本没有办法将url传递进去,
因此外面在getNews函数内部调用next,并进行参数传递 。
function getNews(url){
$.get(url,function(data){
console.log(data)
let url = 'http://localhost:3000'+data.commentUrl;
SX.next(url)//第二次调用next
})
}
function* sendXml(){
let url = yield getNews('http://localhost:3000/news?id=2') //获取新闻
yield getNews(url) //获取评论
}
//获取遍历器对象
let SX = sendXml();
SX.next()//第一次调用next
我们第二个next传递的参数会作为第一个yield的返回值,然后在进行 yield getNews(url)此时评论获取成功
相关文章
- Ramda 哪些让人困惑的函数签名规则
- UITextView 手势触发 TouchesBegan 函数
- 函数类的学习
- VC++ 使用BitBlt函数显示位图「建议收藏」
- HashMap 计算 Hash 值的扰动函数
- 【C 语言】文件操作 ( 按照单个字符的方式读写文件 | fgetc 函数 | fputc 函数 )
- 详解MySQL中存储函数创建与触发器设置
- Hive学习之路 (十六)Hive分析窗口函数(四) LAG、LEAD、FIRST_VALUE和LAST_VALUE详解大数据
- MySQL中使用月份函数的简单方法(MySQL月份函数)
- 解决Oracle函数传入多个参数问题(oracle传入多个参数)
- 利用Oracle LEG函数计算三角形面积(oracle leg函数)
- PHP中一个控制字符串输出的函数
- C#中HTML字符转换函数分享