交互简图
ajax
ajax简易流程
创建对象XHR new XMLHttpRequest
配置open(请求方式,请求地址,是否异步)
send
接受数据,注册事件
小示例
var xhr = new XMLHttpRequest();
xhr.open('GET', '/api/data', true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send();
xhr.onload = function() {
if (xhr.status === 200) {
var responseData = JSON.parse(xhr.responseText);
console.log(responseData);
}
};
ajax同步异步
同步(Synchronous)AJAX:
同步AJAX是指在发送AJAX请求后,浏览器会等待服务器返回响应之后再继续执行后续的操作。在同步模式下,浏览器会阻塞页面的其他操作,直到接收到完整的响应或者超时。这意味着在同步AJAX请求期间,用户无法与页面进行交互,页面会处于“冻结”状态。
示例:
var xhr = new XMLHttpRequest();
xhr.open('GET', '/api/data', false); // 第三个参数设为false表示同步请求
xhr.send();
console.log(xhr.responseText); // 在接收到响应后才能执行这行代码
异步(Asynchronous)AJAX:
异步AJAX是指在发送AJAX请求后,浏览器不会等待服务器返回响应,而是立即继续执行后续的操作。在异步模式下,浏览器会将AJAX请求交给浏览器的异步处理机制(如事件循环),然后继续执行后续的代码。当服务器返回响应时,浏览器会触发相应的回调函数来处理响应数据。
示例:
var xhr = new XMLHttpRequest();
xhr.open('GET', '/api/data', true); // 第三个参数设为true表示异步请求
xhr.send();
xhr.onload = function() {
console.log(xhr.responseText); // 在接收到响应后才会执行这个回调函数
};
不要传false
请求方式
get/post/put/delete/patch
- GET:用于从服务器获取资源。GET请求的特点是幂等性,即多次发送相同的GET请求,服务器的响应应该是一致的。GET请求将数据附加在URL的末尾,长度有限制,适用于获取数据。
- POST:用于向服务器提交数据。POST请求的特点是非幂等性,即多次发送相同的POST请求,服务器的响应可能会有所不同。POST请求将数据放在请求体中,没有对数据长度的限制,适用于提交数据。
- PUT:用于更新服务器上的资源。PUT请求是幂等的,即多次发送相同的PUT请求,服务器的资源应该是一致的。PUT请求将数据放在请求体中,用于更新整个资源。
- DELETE:用于删除服务器上的资源。DELETE请求是幂等的,即多次发送相同的DELETE请求,服务器的响应应该是一致的。DELETE请求没有请求体,用于删除资源。
- PATCH:用于部分更新服务器上的资源。PATCH请求是非幂等的,即多次发送相同的PATCH请求,服务器的响应可能会有所不同。PATCH请求将数据放在请求体中,用于部分更新资源。
- HEAD:获取服务器响应的头信息,但不获取响应体。HEAD请求用于仅获取资源的元数据,如响应头中的Content-Type、Content-Length等。
- OPTIONS:获取服务器支持的请求方法和响应头信息。OPTIONS请求用于了解服务器所支持的请求方法,方便客户端进行下一步的请求。
- CONNECT:建立与目标资源之间的隧道。CONNECT请求用于与代理服务器建立加密连接,通常用于HTTPS代理。
- HEADER:用于在请求中添加自定义的请求头信息。HEADER请求可以通过添加自定义的请求头来传递特定的信息。
例如
var xhr = new XMLHttpRequest();
xhr.open('GET', 'ajax_info.txt', true);
xhr.send();
ajax-封装
在JavaScript中,我们通常会封装Ajax请求,以便更方便地使用它。以下是一个简单的Ajax封装的例子:
function ajax(options) {
// 创建一个XMLHttpRequest对象
var xhr = new XMLHttpRequest();
// 处理返回数据
xhr.onreadystatechange = function() {
if(xhr.readyState === 4) {
if(xhr.status === 200) {
options.success && options.success(xhr.responseText);
} else {
options.error && options.error(xhr.status);
}
}
}
// 处理请求参数
var params = '';
for(var key in options.data) {
params += key + '=' + options.data[key] + '&';
}
params = params.substr(0, params.length - 1);
// 根据请求类型发送请求
if(options.type === 'GET') {
xhr.open('GET', options.url + '?' + params, true);
xhr.send(null);
} else if(options.type === 'POST') {
xhr.open('POST', options.url, true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send(params);
}
}
这个封装的函数可以接受一个options对象作为参数,其中可以包含以下属性:
type:请求类型,可以是'GET'或'POST'。url:请求的URL。data:发送的数据,应该是一个对象。success:一个在请求成功时调用的函数,该函数接受服务器返回的数据作为参数。error:一个在请求失败时调用的函数,该函数接受HTTP状态码作为参数。
例如,我们可以这样使用这个函数:
ajax({
type: 'GET',
url: 'test.php',
data: {name: 'John', age: 30},
success: function(response) {
console.log('Data received: ' + response);
},
error: function(status) {
console.log('Error: ' + status);
}
});
这样,我们可以更方便地发送Ajax请求,而不需要每次都创建和配置XMLHttpRequest对象。
ajax-前后端交互案例
回调地狱问题
在JavaScript中,当我们使用AJAX进行异步操作时,经常会遇到需要多个操作按顺序执行的情冚。例如,我们需要先从服务器获取数据,然后使用这些数据进行下一步操作,然后再进行下一步操作。
如果我们使用传统的回调函数来处理这种情况,代码会变得非常复杂,这就是所谓的“回调地狱”。例如:
ajax('url1', function(response1) {
ajax('url2', function(response2) {
ajax('url3', function(response3) {
// do something with response1, response2 and response3
});
});
});
这种代码的问题在于,它们的嵌套使得代码的阅读和理解变得困难,而且如果我们需要处理错误,那么每个回调函数都需要添加错误处理代码,这使得代码更加复杂。
promise基础语法
在JavaScript中,Promise是一种处理异步操作的对象。它可以代表一个值,该值可能是当前已知的,也可能是在某个时间点在未来才知道。Promise主要有三种状态:pending(待定),fulfilled(已实现),rejected(已拒绝)。
Promise的基础语法如下:
let promise = new Promise(function(resolve, reject) {
// some code
if (/* everything is fine */) {
resolve("Worked!");
} else {
reject(Error("It broke"));
}
});
// 使用.then方法处理resolve和reject的结果
promise.then(function(result) {
console.log(result); // "Worked!"
}, function(err) {
console.log(err); // Error: "It broke"
});
在这个例子中,Promise构造函数接受一个函数作为参数,这个函数带有两个参数:resolve和reject,分别用于处理成功和失败的情况。
.then方法接受两个参数:一个是promise成功时的回调,另一个是promise失败时的回调。
promise封装ajax
以下是一个使用Promise封装ajax请求的案例,其中包含了详细的注释:
// 定义一个函数,接受url, method, data作为参数
function ajax(url, method, data) {
// 返回一个新的Promise对象
return new Promise(function(resolve, reject) {
// 创建一个新的HTTP请求
var xhr = new XMLHttpRequest();
// 初始化一个新的请求
xhr.open(method, url);
// 设置请求头,以便服务器知道如何处理传入的请求
xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
// 当请求加载完成时,此函数将被调用
xhr.onload = function() {
// 如果请求成功完成,HTTP状态码在200-299之间,则调用resolve函数
if (xhr.status >= 200 && xhr.status < 300) {
// 使用请求的响应(response)来resolve promise
resolve(xhr.response);
} else {
// 否则,使用请求的状态文本来reject promise
reject(Error(xhr.statusText));
}
};
// 当请求发生错误时,此函数将被调用
xhr.onerror = function() {
// 使用"网络错误"来reject promise
reject(Error("网络错误"));
};
// 如果有数据需要发送,将其转换为JSON字符串,否则发送null
var sendData = data ? JSON.stringify(data) : null;
// 发送请求
xhr.send(sendData);
});
}
// 使用示例
// 调用我们定义的ajax函数,进行GET请求
ajax('https://api.example.com/data', 'GET')
// 如果请求成功,then方法会被调用
.then(response => {
console.log('Data loaded successfully');
// 解析并打印返回的数据
console.log(JSON.parse(response));
})
// 如果请求失败,catch方法会被调用
.catch(error => {
console.log('An error occurred');
// 打印错误信息
console.log(error);
});
这个例子中,我们创建了一个ajax函数,它接受一个URL、一个HTTP方法(如'GET'或'POST')和一个可选的数据对象。然后,它创建并返回一个新的Promise对象。如果HTTP请求成功完成,Promise将被resolve(使用HTTP响应作为结果),否则将被reject(使用一个Error对象来表示错误)。
async和await语法
一、async和 await
promise使用.then链式调用,但也是基于回调函数async/await更加优雅的异步编程的写法
1.它是消灭异步回调的终极武器
2.它是同步语法,也就是用同步的写法写异步的代码
案例1:promise异步加载图片
- 分别使用 .then 和 await 来获取结果
- 区别
1.await 完全没有回调函数
2.await 是同步写法,异步操作
3.await 后面不仅仅可以接 promise对象,还可以接 async 函数
//里面函数为AJAX,因此是异步任务
let loadImg = (url)=>{
const p = new Promise((resolve,reject)=>{
let newImg = document.createElement("img")
newImg.src = url
newImg.onload = function(){
resolve(newImg)
}
newImg.error = function(){
reject(new Error('Could not load Image at url'))
}
})
return p
}
//通过 .then 来获取结果
loadImg(url1)
.then((img)=>{
console.log(img.width,img.height)
document.body.appendChild(img)
return loadImg(url2)
})
.then((img)=>{
console.log(img.width,img.height)
document.body.appendChild(img)
})
.catch((err)=>{
console.log(err)
})
//使用 async 和 await 的方法来写,立即执行函数
(async function(){
// loadImg(url1) 返回 promise 对象
// await 可以拿到从 resolve 传递过来的 dom 对象
const img1 = await loadImg(url1)
document.body.appendChild(img1)
const img2 = await loadImg(url2)
document.body.appendChild(img2)
})()
//await 接 async 函数
async function loadImg1(){
const img1 = await loadImg(url1)
return img1
}
(async function(){
//img1可以拿到 resolve 里面的值
const img1 = await img1
document.body.appendChild(img1)
})()
async 和 await(详解)_async和await详解_一生注定学霸命的博客-CSDN博客
总结
累累累累累累