1. 程式人生 > >理解 ES6 Generator-next()方法

理解 ES6 Generator-next()方法

lB users meta lba content node failed fail class

  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>

理解 ES6 Generator-next()方法