平时我们使用的axios或者fetch请求数据,是可以支持链式调用的,今天我们就来把原生的ajax请求方式使用Promise封装一翻,配合asnyc和await实现使用同步书写方式来异步代码。是不是很爽啊,好了直接贴代码吧!
第一步:前期准备工作,算是一些辅助小工具;
// 创建 AJAX 对象
function getXHR () {
var xhr = undefined;
if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
} else {
xhr = new ActiveXObject('Microsoft.XMLHTTP');
}
return xhr;
}
// 对象转 GET 参数
function urlToGetPar (parObj) {
if (!parObj) return '';
var str = '?';
for (var key in parObj) {
str += key + '=' + parObj[key] + '&';
}
str = str.substr(0, str.length - 1);
return str;
}
// 对象转 POST 参数
function urlToPostPar (parObj) {
if (!parObj) return '';
var str = '';
for (var key in parObj) {
str += key + '=' + parObj[key] + '&';
}
str = str.substr(0, str.length - 1);
return str;
}
// 给请求地址末尾补斜框
function handleUrl (url) {
if (!url) return '';
if (url.endsWith('/')) {
return url;
} else {
return url + '/';
}
}
// 处理传输的 ID 参数
function handleID (ids) {
if (!ids) return '';
if (Object.prototype.toString.call(ids) === '[object String]') {
return ids.replace(/ /g, '');
} else if (Object.prototype.toString.call(ids) === '[object Array]') {
return ids.join();
} else if (Object.prototype.toString.call(ids) === '[object Number]') {
return ids;
}
}
// 处理返回的结果
function formatData (str) {
var res = undefined;
try {
res = JSON.parse(str);
} catch (err) {
res = str;
}
return res;
}第二步、正式封装请求函数,和上面小工具可以放在一页 js 文件中;
// 创建一个 GET 请求
function getData (option) {
return new Promise (function (resolve, reject) {
var xhr = getXHR();
xhr.open('GET', option.url + urlToGetPar(option.params), option.async !== undefined ? option.async : true);
xhr.send();
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200 || xhr.status === 304) {
resolve(formatData(xhr.responseText));
} else {
reject({
err_code: xhr.status,
err_msg: resolve(formatData(xhr.responseText))
});
}
}
}
})
}
// 创建一个 POST 请求
function postData (option) {
return new Promise (function (resolve, reject) {
var xhr = getXHR();
xhr.open('POST', option.url, option.async !== undefined ? option.async : true);
xhr.setRequestHeader('Content-Type', option.contentType !== undefined ? option.async :'application/x-www-form-urlencoded');
xhr.send(urlToPostPar(option.params));
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200 || xhr.status === 304) {
resolve(formatData(xhr.responseText));
} else {
reject({
err_code: xhr.status,
err_msg: resolve(formatData(xhr.responseText))
});
}
}
}
})
}
// 创建一个 PUT 请求
function putData (option) {
return new Promise(function (resolve, reject) {
var xhr = getXHR();
xhr.open('PUT', handleUrl(option.url) + option.id, option.async !== undefined ? option.async : true);
xhr.setRequestHeader('Content-Type', option.contentType !== undefined ? option.async :'application/x-www-form-urlencoded');
xhr.send(urlToPostPar(option.params));
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200 || xhr.status === 304) {
resolve(formatData(xhr.responseText));
} else {
reject({
err_code: xhr.status,
err_msg: resolve(formatData(xhr.responseText))
});
}
}
}
})
}
// 创建一个 DELETE 请求
function deleteData (option) {
return new Promise(function (resolve, reject) {
var xhr = getXHR();
xhr.open('DELETE', handleUrl(option.url) + handleID(option.id), option.async !== undefined ? option.async : true)
xhr.send();
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200 || xhr.status === 304) {
resolve(formatData(xhr.responseText));
} else {
reject({
err_code: xhr.status,
err_msg: resolve(formatData(xhr.responseText))
});
}
}
}
})
}
发表评论