要是实在不知道要干什么,那就喝两杯思路就来了!

导航菜单

使用Promise封装AJAX

平时我们使用的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))
					});
				}
			}
		}
	})
}


发表评论