请教一段 js 生成器的代码

2021-12-28 20:01:20 +08:00
 wjx0912

function ajax(url, callback) { console.log('ajax enter: ', url) // 1 、创建 XMLHttpRequest 对象 var xmlhttp if (window.XMLHttpRequest) { xmlhttp = new XMLHttpRequest() } else { // 兼容早期浏览器 xmlhttp = new ActiveXObject('Microsoft.XMLHTTP') } // 2 、发送请求 xmlhttp.open('GET', url, true) xmlhttp.send() // 3 、服务端响应 xmlhttp.onreadystatechange = function () { if (xmlhttp.readyState === 4 && xmlhttp.status === 200) { var obj = JSON.parse(xmlhttp.responseText) // console.log(obj) callback(obj) } } console.log('ajax leave: ', url) }

function request(url) { console.log('request enter, url: ', url) ajax(url, res => { console.log('callback enter, url: ', url) getData.next(res) console.log('callback leave, url: ', url) }) console.log('request leave, url: ', url) }

function* gen() { let res1 = yield request('http://www.httpbin.org/get?q=test1') console.log('res1: ', res1) let res2 = yield request('http://www.httpbin.org/get?q=test2') console.log('res2: ', res2) let res3 = yield request('http://www.httpbin.org/get?q=test3') console.log('res3: ', res3) } let getData = gen() getData.next()

问题就是,为什么可以顺序执行?

yield 后面一般跟一个值,但是这里是个函数,request 没有返回值也就是返回了 undefined , 为什么可以等待后台的 ajax 执行完呢?

刚学到生成器,可能比较基础吧。希望不吝指导。

1883 次点击
所在节点    JavaScript
8 条回复
wjx0912
2021-12-28 20:03:57 +08:00
lisianthus
2021-12-28 20:27:00 +08:00
res 的值是通过 next 传过来的 ,代码的第 28 行
lisianthus
2021-12-28 20:28:21 +08:00
Zhuzhuchenyan
2021-12-28 20:29:36 +08:00
简单来说,
let result = yield func()
此时 result 的值和 func 的返回值没有丝毫关系,你如果在看书的话可以接着往下看,yield 的作用只是暂停当前生成器的运行然后等待下一次的 next 调用,并把下一次 next 调用传递的参数传递给 result ,你可以参考一下下面的例子

function doSomething() {
setTimeout(() => {
gen.next("result")
},0)
}

function* generatorFunction() {
const result = yield doSomething()
console.log(result)
}

var gen = generatorFunction()
gen.next()
wjx0912
2021-12-28 20:52:55 +08:00
@lisianthus 谢谢。资料很不错
wjx0912
2021-12-28 20:55:43 +08:00
@Zhuzhuchenyan
再请教下,按您上面的例子:

function doSomething() {
return "abc"
}

这里面没有 next ,相当于 const result = yield "abc"
这种情况下就是不需要 next 了,对吧?
rodrick
2021-12-29 13:46:19 +08:00
生成器相关有兴趣可以读一下 <你不知道的 js>中卷 写的比较清晰 你不要想的太复杂 let a = yield xxxx , yield 的作用就是在一次 next()调用后 到这里停止 把 yield 后面的东西执行(函数就执行 基础变量类型就返回) 然后等待下一次 next(aa)调用的试试 把 aa 塞到 yield 的位置 这里就是把 aa 赋值给了 a 你代码里就是 getData.next(res)的 res 赋值给 res1 这样 然后继续往下走 直到 done:true 为止
"equest 没有返回值也就是返回了 undefined , 为什么可以等待后台的 ajax 执行完呢?" 能等待是因为你再 ajax 执行完了才调用了 next
wjx0912
2021-12-30 11:14:05 +08:00
@rodrick
谢谢 书买了~~~

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/824963

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX