Как видно из примеров прошлых тем для создания ajax-запросов используются фактически повторяющиеся вызовы, которые отличаются лишь деталями - строкой запроса, функциями обработки ответа. И вполне было бы не плохо создать для всех действий, связанных с асинхронным ajax-запросом, создать какую-то общую абстракцию и затем использовать ее при следующих обращениях к серверу.
Для создания дополнительного уровня абстракции в данном случае удобно применять объект Promise, который обертывает асинхронную операцию в один объект, который позволяет определить действия, выполняющиеся при успешном или неудачном выполнении этой операции.
Инкапсулируем асинхронный запрос в объект Promise:
function get(url) { return new Promise((succeed, fail) => { const xhr = new XMLHttpRequest(); xhr.open("GET", url); xhr.addEventListener("load", () => { if (xhr.status >=200 && xhr.status < 400) succeed(xhr.response); else fail(new Error(`Request failed: ${xhr.statusText}`)); }); xhr.addEventListener("error", () => fail(new Error("Network error"))); xhr.send(); }); }
Метод get получает в качестве параметра адрес ресурса сервера и возвращает объект Promise. Конструктор Promise в качестве параметра принимает функцию обратного вызова, которая в свою очередь принимает два параметра - две функции: одна выполняется при успешной обработке запроса, а вторая - при неудачной.
Допустим, в качестве сервера выступает следующее простенькое приложение на Node.js:
const http = require("http"); const fs = require("fs"); http.createServer(function(request, response){ if(request.url == "/hello"){ response.end("XMLHttpRequest на METANIT.COM"); } else{ fs.readFile("index.html", (_error, data) => response.end(data)); } }).listen(3000, ()=>console.log("Сервер запущен по адресу http://localhost:3000"));
Теперь вызовем метод get для осуществления запроса к серверу:
get("http://localhost:3000/hello") .then(response => console.log(response)) .catch(error => console.error(error));
Для обработки результата объекта Promise вызывается метод then(), который принимает два параметра: функцию, вызываемую при успешном выполнении запроса, и функцию, которая вызывается при неудачном выполнении запроса.
В данном случае функция в первом вызове метода then получает ответ сервера и выводит его на консоль.
Для обработки ошибок мы мы можем использовать метод catch(), в который передается функция обработки ошибок.
Подобным образом через Promise можно было бы отправлять данные на сервер:
function post(url, data) { return new Promise((succeed, fail) => { const xhr = new XMLHttpRequest(); xhr.open("POST", url); xhr.addEventListener("load", () => { if (xhr.status >=200 && xhr.status < 400) succeed(xhr.response); else fail(new Error(`Request failed: ${xhr.statusText}`)); }); xhr.addEventListener("error", () => fail(new Error("Network error"))); xhr.send(data); }); } post("http://localhost:3000/user", "Tom") .then(response => console.log(response)) .catch(error => console.error(error));
В даннном случае по адресу "http://localhost:3000/user" будет отправляться строка "Tom".