GOOGLE ADS

среда, 27 апреля 2022 г.

Как отделить XMLHttpRequest от основной функции для лучшей видимости/тестируемости (без 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.
}


Решение проблемы

Вы можете реализовать 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);
}

Комментариев нет:

Отправить комментарий

Laravel Datatable addColumn returns ID of one record only

Я пытаюсь использовать Yajra Datatable для интеграции DataTable на свой веб-сайт. Я смог отобразить таблицу, но столкнулся с проблемой. В по...