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