之前跟同事探讨一个Ajax的问题:ajax是否可以封装一下,实现其他类库如Axios的单例模式呢?对当时的结论不置可否,今天验证一下
服务端代码准备
通过express写一些基础代码:
const express = require('express');
const path = require('path')
const app = express();
// 提供一个接口
app.get("/api/greeting",(req,res,next)=>{
console.log('收到请求!');
res.send("Nice to see you!");
})
//监听3000端口
app.listen(3000,()=>{
console.log('server on 3000!');
})
客户端代码
客户端并发两个请求
var xhr = new XMLHttpRequest();
xhr.onload = function(event){
console.log(event.target.responseText)
}
function sendRequest(){
xhr.open("get","/api/greeting");
xhr.send();
}
//第一个请求
sendRequest()
//第二个请求
sendRequest();
服务端打印显示两次请求均已收到:
客户端网络控制台显示第一个请求被取消了(其实发出去了,但是浏览器将其丢弃了):
XHR实例串行请求
var xhr = new XMLHttpRequest();
function sendRequest() {
return new Promise((res, rej) => {
xhr.onload = function (event) {
res(event.target.responseText);
};
xhr.open("get", "/api/greeting");
xhr.send();
});
}
//请求一
sendRequest().then(data=>{
console.log(data)
//请求二
return sendRequest()
}).then(data=>{
console.log(data)
})
结论
总结一下就是:xhr支持单例模式,使用一个实例负责所有请求,但是只能串行,并行会自动忽略前面未拿到响应的请求。
可以通过工厂函数实时创建新XHR实例,单个实例负责一次请求,用完丢弃。
例如jQuery里的做法:
每次send请求时都会调用工厂方法xhr(),xhr方法实时生成一个XMLHttpRequest实例