今天得要體會一下Generator 來處理非同步有什麼好處
我們假設有3個檔案 分別是 a.txt/b.txt/c.txt
然後要依照順序
一個一個
把裡面的內容依序塞進網頁上的3個div裡面
先來寫一段xhr 我們先不考慮error 的部份
實際程式可以參考 codepen/scripts
//create myAjax function
const myAjax = (url, succFunc, failFunc) => {
const xhr = new XMLHttpRequest();
xhr.open("GET", url);
xhr.onreadystatechange = function() {
if (this.readyState == 4) {
if (this.status == 200) {
succFunc(this.response);
} else {
failFunc(new Error(this.statusText));
}
}
};
xhr.send();
};
// get div
const divAll = document.querySelectorAll("div");
// set text to div
myAjax("../file/a.txt", data => {
divAll[0].innerHTML = data;
});
如果依照往例寫 callback 地獄的話
得寫個波動拳往裡面一直寫,但現在改用generator 呢?
該怎麼寫呢?
記得我們學過 每一次的next 都會執行到 yield 後面的程式
所以我們把每一次的myAjax 都放在yield 後面
我們先來定義一個 Generator
function* mGajax(){
divAll[0].innerHTML = yield request("../file/a.txt");
divAll[1].innerHTML = yield request("../file/b.txt");
divAll[2].innerHTML = yield request("../file/c.txt");
}
const mG=mGajax();
mG.next();
function request(url){
myAjax(url,data=>mG.next(data));
}
先來理解一下
我們先定義好我們的generator ,先不管yield 後面是做什麼
再來我們必需先執行這個generator 並把他asign 給mG 這個變數
好了,我們要啟動這個generator
接下來就是重點了
我們知道,啟動next 他會跑到第1個yield 後面的程式
那這邊是不是就要去執行 myAjax 了呢?
沒錯,所以我們把myAjax 放在我們下面定義的request 裡面
好 眼睛雪亮的你,應該有發現裡面還有個mG.next()
這邊就是重點中的重點
我們知道next 會執行yield 後面的程式,在成功之後
會把值傳回給yield ,而我們下一次的next(data)
也就能賦值給 divAll[0].innerHTML