AJAX
let xhr = new XMLHttpRequest()
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
}
}
xhr.onprogress = function (event) {
if (event.lengthComputable) {
var complete = (event.loaded / event.total * 100 | 0);
progress.value = complete;
}
}
xhr.open('get', '/getInfo')
// 设置请求头
xhr.setRequestHeader()
// 超时控制
xhr.timeout =
xhr.ontimeout = function () {}
// 中止请求
xhr.abort()
// 发送请求
xhr.send()
readyState | 描述 |
---|---|
0 | XHR已经创建,但未调用open()方法 |
1 | open()方法已经被调用 |
2 | send() 方法已经被调用 |
3 | 正在接收响应的内容 |
4 | 成功接收到响应 |
With Callback
const Ajax = ({
method = 'get',
url = '/',
data,
async = true
}, callback) => {
let xhr = new XMLHttpRequest()
xhr.onreadystatechange = () => {
if (xhr.readyState === 4 && xhr.status === 200) {
let res = JSON.parse(xhr.responseText)
callback(res)
}
}
xhr.open(method, url, async)
if (method === 'get') {
xhr.send()
}
if (method === 'post') {
let type = typeof data
let header
if (type === 'string') {
header = 'application/x-www-form-urlencoded'
}
else {
header = 'application/json'
data = JSON.stringify(data)
}
xhr.setRequestHeader('Content-type', header)
xhr.send(data)
}
}
Ajax.get = (url, callback) => {
return Ajax({
url
}, callback)
}
Ajax.post = function (url, data, callback) {
return Ajax({
method: 'post',
url,
data,
}, callback)
}
Ajax.get('http://localhost:3000/getData', (res) => {
console.log(res)
})
With Promise
const Ajax = ({
method = 'get',
url = '/',
data,
async = true
}) => {
return new Promise((resolve, reject) => {
let xhr = new XMLHttpRequest()
xhr.onreadystatechange = () => {
if (xhr.readyState === 4 && xhr.status === 200) {
let res = JSON.parse(xhr.responseText)
resolve(res)
}
}
xhr.open(method, url, async)
if (method === 'get') {
xhr.send()
}
if (method === 'post') {
let type = typeof data
let header
if (type === 'string') {
header = 'application/x-www-form-urlencoded'
}
else {
header = 'application/json'
data = JSON.stringify(data)
}
xhr.setRequestHeader('Content-type', header)
xhr.send(data)
}
})
}
Ajax.get = (url) => {
return Ajax({
url
})
}
Ajax.get('http://localhost:3000/getData')
.then((data) => {
console.log(data)
})
With Generator
const Ajax = ({
method = 'get',
url = '/',
data,
async = true
}) => {
return new Promise((resolve, reject) => {
let xhr = new XMLHttpRequest()
xhr.onreadystatechange = () => {
if (xhr.readyState === 4 && xhr.status === 200) {
let res = JSON.parse(xhr.responseText)
resolve(res)
}
}
xhr.open(method, url, async)
if (method === 'get') {
xhr.send()
}
if (method === 'post') {
let type = typeof data
let header
if (type === 'string') {
header = 'application/x-www-form-urlencoded'
}
else {
header = 'application/json'
data = JSON.stringify(data)
}
xhr.setRequestHeader('Content-type', header)
xhr.send(data)
}
})
}
Ajax.get = (url) => {
return Ajax({
url
})
}
function* use() {
let data = yield Ajax.get('http://localhost:3000/getData')
console.log(data)
}
let obj = use()
obj.next().value.then((res) => {
obj.next(res)
})
With Generator + Co
const Ajax = ({
method = 'get',
url = '/',
data,
async = true
}) => {
return new Promise((resolve, reject) => {
let xhr = new XMLHttpRequest()
xhr.onreadystatechange = () => {
if (xhr.readyState === 4 && xhr.status === 200) {
let res = JSON.parse(xhr.responseText)
resolve(res)
}
}
xhr.open(method, url, async)
if (method === 'get') {
xhr.send()
}
if (method === 'post') {
let type = typeof data
let header
if (type === 'string') {
header = 'application/x-www-form-urlencoded'
}
else {
header = 'application/json'
data = JSON.stringify(data)
}
xhr.setRequestHeader('Content-type', header)
xhr.send(data)
}
})
}
Ajax.get = (url) => {
return Ajax({
url
})
}
function* use() {
let data = yield Ajax.get('http://localhost:3000/getData')
console.log(data)
}
co(use)
Co模块的原理类似如下
function co(gen){
var g = gen();
function next(data){
var result = g.next(data);
if (result.done) return result.value;
result.value.then(function(data){
next(data);
});
}
next();
}
With Async
其实async可以看成Generator + co的集成,不同的是关键字分别用async和await代替了*和yield,更加的语义化。除此之外,async函数会返回一个Promise对象。
const Ajax = ({
method = 'get',
url = '/',
data,
async = true
}) => {
return new Promise((resolve, reject) => {
let xhr = new XMLHttpRequest()
xhr.onreadystatechange = () => {
if (xhr.readyState === 4 && xhr.status === 200) {
let res = JSON.parse(xhr.responseText)
resolve(res)
}
}
xhr.open(method, url, async)
if (method === 'get') {
xhr.send()
}
if (method === 'post') {
let type = typeof data
let header
if (type === 'string') {
header = 'application/x-www-form-urlencoded'
}
else {
header = 'application/json'
data = JSON.stringify(data)
}
xhr.setRequestHeader('Content-type', header)
xhr.send(data)
}
})
}
Ajax.get = (url) => {
return Ajax({url})
}
async function use() {
let data = await Ajax.get('http://localhost:3000/getData')
console.log(data)
}
use()
补充一个常见的问题
async function A() { // 这代码一看就有问题
let arr = []
await fetch()
arr.forEach(async item => {
await fetch(item)
})
console.log(1)
}
async function A() { // 应该写成这样
let arr = []
let pArr = []
await fetch()
for (let item of arr) {
pArr.push(fetch(item))
}
const data = await Promise.all(pArr)
}
Axios
可以使用现成的AJAX库Axios,当然也可以采用下一节介绍的浏览器自带的Fetch来发请求
axios({
method: 'post',
url: '/user/12345',
data: {
firstName: 'Fred',
lastName: 'Flintstone'
}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});