如何将 XMLHttpRequest 与主函数分开以获得更好的 visbility/testibility(无承诺/asnyc/await)
How to separate XMLHttpRequest from the main function for better visbility/testibility (without Promises / asnyc/await )
想象一下这个函数:
function myMainFunction() {
doSomeInitialStuff();
// more stuff..
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState == XMLHttpRequest.DONE) {
// Now that we know we received the result, we can do the heavy lifting here
if (xhr.status == 200) {
console.log("ready 200");
let result = JSON.parse(xhr.responseText);
doStuff(result);
// and much more stuff..
} else {
console.log("error", xhr.status);
return undefined;
}
}
};
xhr.open("GET", "http://example.com", true);
xhr.send(null);
}
这个很好用,但是没法测试,这个功能成了怪物。
所以我想重构它,将所有不同的部分分离成它们自己独特的功能。
问题是,我不知道如何提取 XHR 部分并使其继续工作。
我不能使用 Promises 或 asnyc/await,必须坚持使用普通 XHR。
我通常做的是为 ajax 调用(或本例中的 xhr)创建一个单独的异步函数。只需等待它的结果并从那里开始。容易分离。但是这次我没有等待什么的奢侈。
我想表达的意思是这样的
function refactoredMyMainFunction() {
doSomeInitialStuff();
// more stuff..
let result = xhrFunction();
doStuff(result); // result would be undefined here, since I cannot wait for the xhr request to finish.
}
您可以实施 callback-based API:
function myMainFunction() {
doSomeInitialStuff();
// more stuff..
xhrFunction(doStuff);
}
function xhrFunction(cb) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState == XMLHttpRequest.DONE) {
// Now that we know we received the result, we can do the heavy lifting here
if (xhr.status == 200) {
console.log("ready 200");
let result = JSON.parse(xhr.responseText);
cb(result);
// and much more stuff..
} else {
console.log("error", xhr.status);
return undefined;
}
}
};
xhr.open("GET", "http://example.com", true);
xhr.send(null);
}
想象一下这个函数:
function myMainFunction() {
doSomeInitialStuff();
// more stuff..
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState == XMLHttpRequest.DONE) {
// Now that we know we received the result, we can do the heavy lifting here
if (xhr.status == 200) {
console.log("ready 200");
let result = JSON.parse(xhr.responseText);
doStuff(result);
// and much more stuff..
} else {
console.log("error", xhr.status);
return undefined;
}
}
};
xhr.open("GET", "http://example.com", true);
xhr.send(null);
}
这个很好用,但是没法测试,这个功能成了怪物。
所以我想重构它,将所有不同的部分分离成它们自己独特的功能。
问题是,我不知道如何提取 XHR 部分并使其继续工作。
我不能使用 Promises 或 asnyc/await,必须坚持使用普通 XHR。
我通常做的是为 ajax 调用(或本例中的 xhr)创建一个单独的异步函数。只需等待它的结果并从那里开始。容易分离。但是这次我没有等待什么的奢侈。
我想表达的意思是这样的
function refactoredMyMainFunction() {
doSomeInitialStuff();
// more stuff..
let result = xhrFunction();
doStuff(result); // result would be undefined here, since I cannot wait for the xhr request to finish.
}
您可以实施 callback-based API:
function myMainFunction() {
doSomeInitialStuff();
// more stuff..
xhrFunction(doStuff);
}
function xhrFunction(cb) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState == XMLHttpRequest.DONE) {
// Now that we know we received the result, we can do the heavy lifting here
if (xhr.status == 200) {
console.log("ready 200");
let result = JSON.parse(xhr.responseText);
cb(result);
// and much more stuff..
} else {
console.log("error", xhr.status);
return undefined;
}
}
};
xhr.open("GET", "http://example.com", true);
xhr.send(null);
}