ES2015提供的

生成器函数回顾

  1. // 生成器函数回顾
  2. function* foo() {
  3. console.log('start');
  4. // 内部可以随时使用yield向外返回一个值
  5. // yield 不会像return一样立即结束这个函数
  6. // 是暂停了生成器函数的执行
  7. // 直到下此调用next 才会继续往下执行
  8. // const res = yield 'foo'
  9. // console.log(res);
  10. try{
  11. const res = yield 'foo'
  12. console.log(res);
  13. } catch(e){
  14. console.log(e);
  15. }
  16. }
  17. // 调用这个生成器函数不会直接执行而是获得一个生成器对象
  18. const generator = foo();
  19. // 调用next方法函数体才会开始执行
  20. const result = generator.next();
  21. console.log(result);
  22. // 如果next 传入一个参数 内部的yield 是可以接收到这个参数的
  23. // generator.next('bar');
  24. // 如果调用的 throw 那么会对生成器函数内部 抛出一个异常
  25. generator.throw(new Error('error'))

总结:
调用这个生成器函数不会直接执行 而是获得一个生成器对象
调用next方法函数体才会开始执行
如果next 传入一个参数 内部的yield 是可以接收到这个参数的
yield 不会像return一样立即结束这个函数 是暂停了生成器函数的执行 直到下此调用next 才会继续往下执行
如果调用的 throw 那么会对生成器函数内部 抛出一个异常
done属性表示生成器是不是已经结束了
惰性执行 调一次next 往下执行一步

Generator 配合 promise 的异步方案

  1. // Generator 配合 promise 的异步方案
  2. function ajax(url) {
  3. return new Promise(function (resolve, reject) {
  4. var xhr = new XMLHttpRequest()
  5. xhr.open('GET', url)
  6. // HTML5中引入的新特性 请求完成后直接拿到 json对象
  7. xhr.responseType = 'json';
  8. // HTML5中引入的新特性 请求完成后执行
  9. xhr.onload = function () {
  10. if (this.status === 200) {
  11. resolve(this.response)
  12. } else {
  13. reject(new Error(this.statusText))
  14. }
  15. }
  16. xhr.send();
  17. })
  18. }
  19. function * main() {
  20. const users = yield ajax('./api/users.json')
  21. console.log(users);
  22. const posts = yield ajax('./api/posts.json')
  23. console.log(posts);
  24. }
  25. const g = main();
  26. const result = g.next();
  27. result.value.then(data => {
  28. const result2 = g.next(data);
  29. if(result2.done) return
  30. result2.value.then(data => {
  31. const result3 = g.next(data);
  32. if(result3.done) return
  33. result3.valuethen(data => {
  34. g.next(data);
  35. })
  36. })
  37. })

利用生成器函数写出更容易阅读的代码

Generator 配合 promise 的异步方案 —-递归 实现生成器函数执行器

  1. // Generator 配合 promise 的异步方案 利用递归实现更通用的申城其函数的执行器
  2. function ajax(url) {
  3. return new Promise(function (resolve, reject) {
  4. var xhr = new XMLHttpRequest()
  5. xhr.open('GET', url)
  6. // HTML5中引入的新特性 请求完成后直接拿到 json对象
  7. xhr.responseType = 'json';
  8. // HTML5中引入的新特性 请求完成后执行
  9. xhr.onload = function () {
  10. if (this.status === 200) {
  11. resolve(this.response)
  12. } else {
  13. reject(new Error(this.statusText))
  14. }
  15. }
  16. xhr.send();
  17. })
  18. }
  19. function * main() {
  20. try {
  21. const users = yield ajax('./api/users.json')
  22. console.log(users);
  23. const posts = yield ajax('./api/posts.json')
  24. console.log(posts);
  25. const urls = yield ajax('./api/urls111.json')
  26. console.log(urls);
  27. } catch (err) {
  28. console.log(err);
  29. }
  30. }
  31. // 生成器函数执行器
  32. function co(generator){
  33. const g = generator();
  34. function handleResult(result) {
  35. if (result.done) return // 生成器函数结束
  36. result.value.then(data => {
  37. handleResult(g.next(data))
  38. }, error => {
  39. g.throw(error)
  40. })
  41. }
  42. handleResult(g.next());
  43. }
  44. co(main)
  45. // const g = main();
  46. // function handleResult(result) {
  47. // if (result.done) return // 生成器函数结束
  48. // result.value.then(data => {
  49. // handleResult(g.next(data))
  50. // }, error => {
  51. // g.throw(error)
  52. // })
  53. // }
  54. // handleResult(g.next());