理解 ES6 Generator-next()方法

  1 <!DOCTYPE html>
  2 <html lang="en">
  3 <head>
  4     <meta charset="UTF-8">
  5     <title>generator-next</title>
  6 </head>
  7 <body>
  8 
  9     <h3>理解 ES6 Generator-next() 方法</h3>
 10 
 11     <script>
 12         window.onload = function() {
 13             // Generator 异步任务封装
 14 
 15             // 例-1
 16             function* gene() {
 17                 // mark_1
 18                 let url = 'https://api.github.com/';
 19                 let result = yield myAjax(url, 'get', null, successCallBack, failCallBack);
 20                 // mark_2
 21                 let jsRelt = JSON.parse(result);
 22                 console.log('调用第二个 next 后, result 才等于 data: ', jsRelt['current_user_url']);
 23                 yield 'end';
 24                 // mark_3
 25             }
 26 
 27             let gn = gene(); // 返回一个遍历器对象 gn
 28             let first_next = gn.next(); // 调用第一个 next 方法: 启动遍历器, 执行 mark_1 ~ mark_2 之间的代码
 29             console.log('调用第一个 next 后: ', first_next); // 因为异步, first-next: {value: undefined, done: false}
 30 
 31             // ajax 成功的回调函数
 32             function successCallBack(data) {
 33                 console.log('request-successful: !'/*, data*/);
 34                 // * relt = gn.next(data) 说明:
 35                 // * 1. 此处调用第二个 next 方法: 执行 mark_2 ~ mark_3 之间的代码, 返回的对象 relt = {value: "end", done: false}
 36                 // * 2. yield 'end'; 是同步操作, 所以调用第二个 next 方法后 relt.value马上等于 yield 后面表达式的结果("end"),
 37                 // *     不信注释掉第三个 gn.next() 看结果),
 38                 // *     如果 yield 后面跟的是异步操作, 则需调用下一个 next 方法 relt.value 才有值.
 39                 let relt = gn.next(data);
 40 
 41                 console.log('同步操作, relt 立马有值: ', relt);
 42 
 43                 // 已经遍历完所有的 yield 语句, 无论再调用多少个 next() 方法都返回 {value: undefined, done: true}
 44                 console.log('调用第三个 next 返回的对象: ', gn.next() /*第三个next()方法*/);
 45             }
 46             // ajax 失败的回调函数
 47             function failCallBack(err) {
 48                 console.log('request-failed: ', err);
 49             }
 50 
 51             /*
 52                 // 例-2
 53                 var fetch = require('node-fetch');
 54                 function* gen() {
 55                     var url = 'https://api.github.com/users/github';
 56                     var result = yield fetch(url);
 57                     console.log(result.bio);
 58                 }
 59                 // 执行这段代码的方法如下:
 60                 var g = gen();
 61                 var result = g.next();
 62                 result.value.then(function(data) {
 63                     return data.json();
 64                 }).then(function(data) {
 65                     g.next(data);
 66                 });
 67             */
 68 
 69             /*
 70             * Generator-next() 总说明:
 71             * 1.
 72             *     1.1 next(param) 方法的参数 param 表示上一条含 yield 关键字的语句的返回值
 73                     (即: 本条含有 yield 关键字的整条语句(可能还含有其他变量或表达式)的最终返回值为下一个 next() 中的参数), 所以例1 中: result = data;
 74                 1.2 或者说: 一条含有 yield 关键字的表达式语句(如例-1: let result = yield myAjax(url, 'get', null, successCallBack, failCallBack);),
 75                     最终的值(result), 等于下一个next(data) 方法中的参数 data;
 76             * 2. 注意, gn.next() 返回的是一个对象, 其中的 value 属性的值等于其刚执行完的含 yield 关键字的语句 yield 后面的表达式的结果,
 77                  如果这个表达式是同步操作, 那返回的对象中 value 立马有值, 如果是异步操作, 则 value 首先是 undefined, 异步执行完后才有值.
 78             * 3. 执行的代码顺序: 调用第一个 next() 执行 mark_1 ~ mark_2 之间的代码,
 79                  第二个 next() 执行的是 mark_2 ~ mark_3 之间的代码, 以此类推;
 80             * 4. 例-2 作为参考, 摘自《ES6 标准入门(第3版)》阮一峰 著 第 360 页内容.
 81             *
 82             */
 83 
 84 
 85         }
 86 
 87         // ------------ function -------------
 88 
 89 
 90         // 自定义 ajax, 类型仅限于 get 和 post, 回调函数: success/error
 91         function myAjax(url, type, params, success, error) {
 92             var xhr = null;
 93             var args = null;
 94             xhr = new XMLHttpRequest();
 95             xhr.onreadystatechange = function() {
 96                 if (xhr.readyState == 4) {
 97                     if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
 98                         success(xhr.responseText);
 99                     } else {
100                         error("Request was unsuccessful: "+ xhr.status);
101                     }
102                 }
103             };
104             xhr.open(type, url, true); // 类型, 连接, 是否异步
105             if (type.toLowerCase() == 'post') {
106                 // xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); // 默认的表单提交
107                 xhr.setRequestHeader("Content-Type", "application/json; charset=UTF-8"); // JSON.stringify 处理后的json 键值对
108                 args = params;
109             }
110             xhr.send(args);
111         }
112 
113     </script>
114 
115 
116 </body>
117 </html>

猜你喜欢

转载自www.cnblogs.com/Rainscoco/p/9082331.html