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 执行完呢?
刚学到生成器,可能比较基础吧。希望不吝指导。
1
wjx0912 OP |
2
lisianthus 2021-12-28 20:27:00 +08:00
res 的值是通过 next 传过来的 ,代码的第 28 行
|
3
lisianthus 2021-12-28 20:28:21 +08:00
|
4
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() |
5
wjx0912 OP @lisianthus 谢谢。资料很不错
|
6
wjx0912 OP @Zhuzhuchenyan
再请教下,按您上面的例子: function doSomething() { return "abc" } 这里面没有 next ,相当于 const result = yield "abc" 这种情况下就是不需要 next 了,对吧? |
7
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 |