2022-09-16 前后端交互方式总结:Promise定义和用法以及基于Promise 接口调用方式:ajax fetch axios async/await

本文详细介绍了Promise的概念、优势和基本用法,解析了pending, fulfilled和rejected状态,以及resolve和reject的作用。接着探讨了AJAX的工作原理、优缺点和实现步骤,包括xhr.readyState和http状态码。此外,文章还讨论了axios、fetch API以及async/await的使用,最后比较了Promise.all()和Promise.race()的区别和应用场景。" 106016904,8357538,Java实现二叉树剪枝,"['Java', '二叉树剪枝', '遍历树']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

零.Promise

1.什么是Promise?

Promise是JS中进行异步编程的一种新的解决方案,(旧方案是单纯使用回调函数)
语法上,Promise是一个对象,从Promise对象可以获取异步操作的消息

2.使用Promise有什么好处?
  • Promise支持链式调用,可以避免回调地狱(回调地狱的终极解决方案:async/await)
  • Promise对象提供了简介的API,使用控制异步操作变得容易
3.Promise的基本用法
var p = new Promise(function(resolve,reject){//实例化Promise对象
    resolve(data);// 成功时调用 resolve()
    reject(err); // 失败时调用 reject()
});
p.then(function(data){
    console.log(data);// 从resolve得到正常结果,data为resolve中的参数
},function(err){
    console.log(arr);// 从reject得到错误信息,err为reject中的参数
});
4.Promise的基本流程

在这里插入图片描述

5.pending,fulfilled和rejected是什么?
  • Promise类的实例对象是有状态(state)的,对应三个值:pending(待定)、fullfilled(成功)、rejected(失败)
  • 实例的初始状态为pending,一旦由pending状态落定成fulfilled状态或rejected状态,就不可再次改变,该过程是不可逆的
  • 与之对应,Promise类实例对象有成功的结果(value)失败的原因(reason),默认值都为undefined,只有状态被改变后(pending==>fullfilled或者pending==>rejected)才会为其赋值。
Promsie内部的state、value、reason是私有的,外界是访问不到的
6.resolve和reject是什么?

在Promise的实例化对象中,存在一个用于处理异步任务的构造函数
resolve和reject就是该构造函数的两个形参,用于处理成功和失败两种情况

  • resolve作用是,将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;
  • reject作用是,将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。
7.参数executor
什么是executor?

executor(读作:[ɪɡˈzekjətə®]),是带有 resolve 和 reject 两个参数的函数 。即(resolve,reject)=>{...}
Promise构造函数执行时立即调用executor函数,resolve和reject两个函数作为参数传递给executor(executor在Promise构造函数返回新建对象时被调用)

executor的resolve和reject被调用时改变Promise的状态
  • resolve 和 reject 函数被调用时,分别将promise的状态改为fulfilled(完成)或rejected(失败)。
    executor 内部通常会执行一些异步操作
  • 一旦完成,可以调用resolve函数来将promise状态改成fulfilled,
    或者在发生错误时将它的状态改为rejected。
  • 如果在executor函数中抛出一个错误,那么该promise 状态为rejected。
    executor函数的返回值被忽略。
8.then()和catch()是什么?
then方法

then()的作用是为 Promise 实例添加状态改变时的回调函数。
then方法可以有两个参数:

第一个是resolve状态的回调函数
第二个是reject状态的回调函数(可选)

then方法返回的是**一个新的Promise实例(**不是原来那个Promise实例)
回顾:Promise接收一个函数作为参数,这个函数有两个参数,第二个参数可选,分别是resolve和reject,
这两个参数分别和then方法的两个参数对应

catch方法

catch方法就是then方法的语法糖,是.then(null, rejection)或.then(undefined, rejection)的别名
也就是说,catch也是then,它用于捕获错误,它的参数也就是then的第二个参数。

9.Promise.race()和Promise.all()是什么?

promise中的all方法和race方法
这两个方法,都是并行执行多个异步操作
区别:all方法遵循“谁跑得慢,以谁为准执行回调”,race方法遵循的是“谁跑的快,以谁为准执行回调”

示例
        let p1 = Promise.resolve('aaa')
        let p2 = Promise.resolve('bbb')
        let p3 = Promise.reject('ccc')
        let p4 = Promise.resolve('ddd')
        Promise.all([p1, p2, p3, p4]).then(res => {
            console.log(res); //返回数组
        }).catch(err => {
            console.log(err);
        });
        Promise.race([p1, p2, p3, p4]).then(res => {
            console.log(res); //返回数组
        }).catch(err => {
            console.log(err);
        });

结果:先输出aaa,再输出ccc

使用场景

Promise.all()的使用场景:一个操作同时需要不同接口返回的数据
Promise.race()的使用场景:若干服务器的若干接口都提供同样的服务,而不知道哪个接口更快==>哪个接口的数据先回来就用哪个接口的数据。

一.AJAX

1.什么是Ajax?

AJAX(Asynchronous Javascript And XML)即“异步Javascript和XML”,是⼀种创建交互式⽹⻚应
⽤的⽹⻚开发技术
使用Javascript语言与服务器进行异步交互,传输的数据为XML等格式。
可以在不重新加载整个网页的情况下,与服务器交换数据,并且更新部分网页

2.AJAX的特点

当服务器响应时,不用刷新整个浏览器页面,而是可以局部刷新

3.AJAX的原理

在用户与服务器之间加一个中间层(AJAX引擎),
用XMLHttpRequest对象想服务器发送异步请求,从服务器获取数据,
通过javascript来操作DOM,从而更新页面,使得用户操作和服务器响应异步化.

4.AJAX的优缺点
优点
  • 异步交互,增强了交互体验
  • 因为服务器无需响应整个页面,只需要响应部分内容,大大减轻服务器压力
缺点
  • 增多了对服务器的访问次数,给服务器增加了压力
  • AJAX是在浏览器中使用javascript完成的,因此还需要处理浏览器的兼容性问题
  • 不能应用在所有场景,很多时候还需要使用同步交互
5.AJAX的实现步骤
  • 创建XMLHttpRequest对象
  • 通过open()方法与服务器建立连接
  • 构建请求所需的数据内容,并通过send()方法发送给服务器端
  • 通过onreadystatechange事件监听服务器端的通信状态
  • 接收并处理服务器端向客户端响应的数据结果
  • 将处理结果更新到HTML页面中
6.xhr.readyState:返回当前请求的状态
xhr.readyState = 0-未初始化,对象已建立,尚未调用open()
xhr.readyState = 1-初始化,对象建立未调用send()
xhr.readyState = 2-发送数据,send()方法调用,但是当前的状态及http头未知,请求未完成
xhr.readyState = 3-数据传输中,接受部分数据
xhr.readyState = 4-响应内容解析完成
7.xhr.state:http常见状态码
1**~5**的大概意思
1**:请求收到,继续处理
2**:操作成功收到,分析、接受
3**:完成此请求必须进一步处理
4**:请求包含一个错误语法或不能完成
5**:服务器执行一个完全有效请求失败
常见状态码
200(成功)服务器已成功处理了请求。
301,永久性重定向,表示资源已被分配了新的 URL
302,临时性重定向,表示资源临时被分配了新的 URL
400(错误请求)服务器不理解请求的语法
401表示发送的请求需要有通过HTTP认证的认证信息
403(禁止)服务器拒绝请求
404(未找到)服务器找不到请求网页
500(服务器内部错误)服务器遇到错误,无法完成请求
503,表示服务器处于停机维护或超负载,无法处理请求
7.AJAX示例:用户名是否已经存在
代码

user.html

<label for="">用户名:</label>
<input type="text"><span></span>
<br>
<input type="button" value="Send" id="btn">
<script>
    var span = document.querySelector("span");
    //1.创建XMLHttpRequest实例对象
    var xhr = new XMLHttpRequest();
    document.getElementById("btn").addEventListener("click", () => {
    	//2.通过open方法与服务器建立连接
        xhr.open("GET", "./user.php?user=" + document.querySelectorAll("input")[0].value, true);
        //3.通过send方法把数据发送给服务器
        xhr.send();
        //4.使用onreadystatechange事件监听服务器返回的状态
        xhr.onreadystatechange = callback;
    });

    function callback() {
 	   //5.接收和分析服务器返回的数据
        if (xhr.readyState == 4 && xhr.status === 200) {
            // console.log(xhr.response);
            if (xhr.responseText == 1) {
                span.style.color = 'red';
                span.innerHTML = '*用户名已存在!';
            }
            if (xhr.responseText == 2) {
                span.style.color = 'green';
                span.innerHTML = '*注册成功!';
            }
        }
    }

user.php

<?php
  $user=$_GET['user'];
  $arr=['张三','李四','王五'];
  if(in_array($user,$arr)){
    echo 1;
  }else{
    echo 2;
  }
?>
报错:‘null’ has been blocked by CORS policy,遇到跨域问题
解决方法

把代码写在PHPStudy的www文件夹下
打开服务器
把地址栏中www前面的改成localhost
即:http://localhost/user.html

8.AJAX的封装和使用
封装 AJAX
//封装一个ajax请求
function ajax(options) {
    //创建XMLHttpRequest对象
    const xhr = new XMLHttpRequest()
 
 
    //初始化参数的内容
    options = options || {}
    options.type = (options.type || 'GET').toUpperCase()
    options.dataType = options.dataType || 'json'
    const params = options.data
 
    //发送请求
    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.send(params)
 
    //接收请求
    xhr.onreadystatechange = function () {
        if (xhr.readyState === 4) {
            let status = xhr.status
            if (status >= 200 && status < 300) {
                options.success && options.success(xhr.responseText, xhr.responseXML)
            } else {
                options.fail && options.fail(status)
            }
        }
    }
}
使用封装好的ajax()函数
ajax({
    type: 'post',
    dataType: 'json',
    data: {},
    url: 'https://xxxx',
    success: function(text,xml){//请求成功后的回调函数
        console.log(text)
    },
    fail: function(status){请求失败后的回调函数
        console.log(status)
    }
})

三.axios

axios笔记专栏

四.async和await

2022-01-28 async和await的定义和用法
2021-07-28 使用async和await改进Promise异步操作的写法

五.Fetch

1.定义

Fetch是ES6新增的通信方法,不是ajax,但是他本身实现数据通信,就是基于promise管理的
基本特征:

更加简单的数据获取方式,功能更强大、更灵活,可以看做是xhr的升级版
基于Promise实现

语法结构:

fetch(url)
	.then(fn2)
	.then(fn3)
	...
	.catch(fn)

2.基本用法
fetch('/abc').then(data => {
	return data.text() // 返回一个Promise实例对象
}).then(res=>{
	console.log(res)// 注意这里得到的才是最终的数据
})

*text()方法属于fetchAPI的一部分,它返回一个Promise实例对象,用于获取后台返回的数据

3.请求参数
3.1. 常用配置选项
  • method(String):HTTP请求方法,默认为GET(GET、POST、PUT、DELETE)
  • body(String):HTTP的请求参数
  • headers(Object):HTTP的请求头,默认为{}
fetch('/abc',{
	method:'GET'
}).then(data => {
	return data.text() // 返回一个Promise实例对象
}).then(ret=>{
	// 注意这里得到的才是最终的数据
	console.log(ret)
})
3.2.GET请求方式的参数传递(其它方式略)

方式一

// client发送,从server端返回
fetch('/abc?id=123',{
	method:'GET'
}).then(data => {
	return data.text() // 返回一个Promise实例对象
}).then(ret=>{
	console.log(ret)
})

// client发送,从server端返回
fetch('/abc?id=123',{
	method:'GET'
}).then(data => {
	return data.text() // 返回一个Promise实例对象
}).then(ret=>{
	console.log(ret)
})

方式二

// client发送,从server端返回
fetch('/abc/123',{
	method:'GET'
}).then(data => {
	return data.text() // 返回一个Promise实例对象
}).then(ret=>{
	console.log(ret)
})

3.3.响应结果

响应数据格式

  • text():将返回体处理成字符串类型
  • json():返回结果和JSON.parse(responseText)一样
// client发送,从server端返回
fetch('/abc').then(data => {
	// return data.text()
	return data.json()
}).then(data=>{
	console.log(data) // JSON对象
	console.log(data.uname) // JSON对象.属性
})

// server接收,并发送给client
app.get('/abc',(req,res)=>{
	res.json({
		uname: 'lisi',
		age: 13,
		gender: 'male'
	})
})

4.优缺点
fetcht只对网络请求报错,对400500都当做成功的请求,需要封装去处理
fetch默认不会带cookie,需要添加配置项
fetch不支持abort,不支持超时控制,使用setTimeout及Promise.reject的实现的超时控制并不能阻止请求过程继续在后台运行,造成了量的浪费
fetch没有办法原生监测请求的进度,而XHR可以
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端OnTheRun

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值