原理:通过XMLHttpRequest对象向服务器发异步请求,将结果使用Promise返回
function promiseAjax(url, type, data, timeout = 8000) {
return new Promise((resolve, reject) => {
// 请求方式小写转换
type = type.toLocaleLowerCase()
// 新建一个XMLHttpRequest实例
const xhr = new XMLHttpRequest()
// 设置超时时间,超时自动终止
xhr.timeout = timeout
// 判断请求方式,整理数据
if (type === 'get') {
if (data) {
url += '?'
for (let key in data) {
url += (key + '=' + data[key] + '&')
}
url = url.substring(0, url.length - 1)
}
xhr.open(type, url)
xhr.send(null)
}
if (type === 'post') {
xhr.open(type, url)
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
if (data) {
xhr.send(data)
} else {
xhr.send(null)
}
}
// 使用定时器判断是否超时,返回reject
let timer = setTimeout(() => {
reject('请求超时了')
throw new Error('请求超时')
}, timeout)
// 响应回调,获取内容
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
// 转换JSON,可转可不转
let result = JSON.parse(xhr.responseText)
// 清除定时器
clearTimeout(timer)
// resolve
resolve(result)
}
}
}
// 失败回调,reject
xhr.onerror = function(err) {
reject('请求失败,' + err)
}
})
}
测试
promiseAjax('http://jsonplaceholder.typicode.com/posts', 'get', null)
.then(res => {
console.log(res);
})
.catch(err => {
console.log(err);
})
promiseAjax('http://jsonplaceholder.typicode.com/comments', 'get', {
postId: 1
})
.then(res => {
console.log(res);
})
.catch(err => {
console.log(err);
})