理解 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. 按照 《ES6 標準入門(第3版)》阮一峯 著 第 323 頁內容,總結 next() 方法。
 72             *   1.1 next(param) 方法的參數 param 表示上一條含 yield 關鍵字的語句中,yield 後面表達式的結果,
 73                     例-1 中,第一條含 yield 關鍵字的語句中由於沒有其餘表達式組合成更復雜的表達式了,因此 myAjax(...args) 中返回的 data 就等於 result;
 74             * 2. 注意, gn.next() 返回的是一個對象, 其中的 value 屬性的值等於其剛執行完的含 yield 關鍵字的語句 yield 後面的表達式的結果,
 75                  若是這個表達式是同步操做, 那返回的對象中 value 立馬有值, 若是是異步操做, 則 value 首先是 undefined, 異步執行完後纔有值.
 76             * 3. 執行的代碼順序: 調用第一個 next() 執行 mark_1 ~ mark_2 之間的代碼,
 77                  第二個 next() 執行的是 mark_2 ~ mark_3 之間的代碼, 以此類推;
 78             * 4. 例-2 做爲參考, 摘自《ES6 標準入門(第3版)》阮一峯 著 第 360 頁內容.
 79             *
 80             */
 81 
 82 
 83         }
 84 
 85         // ------------ function -------------
 86 
 87 
 88         // 自定義 ajax, 類型僅限於 get 和 post, 回調函數: success/error
 89         function myAjax(url, type, params, success, error) {
 90             var xhr = null;
 91             var args = null;
 92             xhr = new XMLHttpRequest();
 93             xhr.onreadystatechange = function() {
 94                 if (xhr.readyState == 4) {
 95                     if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
 96                         success(xhr.responseText);
 97                     } else {
 98                         error("Request was unsuccessful: "+ xhr.status);
 99                     }
100                 }
101             };
102             xhr.open(type, url, true); // 類型, 鏈接, 是否異步
103             if (type.toLowerCase() == 'post') {
104                 // xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); // 默認的表單提交
105                 xhr.setRequestHeader("Content-Type", "application/json; charset=UTF-8"); // JSON.stringify 處理後的json 鍵值對
106                 args = params;
107             }
108             xhr.send(args);
109         }
110 
111     </script>
112 
113 
114 </body>
115 </html>
相關文章
相關標籤/搜索