后端index.js注册网址并写入数据
- var router=require("./router.js")
- router.get("/news",function(req,res){
- var obj={data:[{title:"新闻1",content:"内容1",id:1},
- {title:"新闻2",content:"内容2",id:2},
- {title:"新闻3",content:"内容3",id:3}
- ]}
- var str=JSON.stringify(obj)
- res.setHeader("content-Type","text/json;charset=utf8")
- res.end(str)
- })
- router.get("/author",function(req,res){
- var obj=[{name:"lily",id:1},
- {name:"lucy",id:2},
- {name:"jack",id:3}
- ]
- var str=JSON.stringify(obj)
- res.setHeader("content-Type","text/json;charset=utf8")
- res.end(str)
- })
前端index.html文件请求news的数据:
- <button onclick="fn()">Ajax请求数据button>
- <script>
- function fn(){
- var xhr=new XMLHttpRequest()||new ActiveXObject("Microsoft.XMLHTTP")
- xhr.open("GET","/news",true) //请求news的数据
- xhr.send()
- xhr.onreadystatechange=function(){
- if(xhr.readyState==4&&xhr.status==200){
- console.log(xhr.responseText)
- //根据业务需求处理数据
- }
- }
- }
- script>
前端index.html文件请求author的数据:
- <button onclick="fn()">Ajax请求数据button>
- <script>
- function fn(){
- var xhr=new XMLHttpRequest()||new ActiveXObject("Microsoft.XMLHTTP")
- xhr.open("GET","/author",true) //请求author的数据
- xhr.send()
- xhr.onreadystatechange=function(){
- if(xhr.readyState==4&&xhr.status==200){
- console.log(xhr.responseText)
- //根据业务需求处理数据
- }
- }
- }
- script>
请求 news 和 author 这两个网址接口的数据就要发送两次Ajax网络请求才能获得不同的数据,若想请求其他接口的数据就要写更多的网络请求代码。这样就很麻烦,因为每次请求的代码是一样的,只是请求的网址和请求到的数据的处理方式不同。所以,可以根据这个特点设计一个网络请求工具来简化代码,使网络请求更灵活。
tool(url,cb):
tool函数就是一个简单的封装了ajax网络请求的工具
tool函数先用ajax请求传入的第一个参数url对应网址
当请求到并返回数据时 就把数据传给cb函数使用(调用cb)去执行业务
此时能满足不同的网址请求和各样的业务,实现代码复用
当fn点击事件发生后,tool工具函数就会请求网址得到数据,再将数据传给业务(回调)函数,开始执行业务
前端index.html文件请求数据:(author.html同理)
- <script src="./tool.js">script>
- <button onclick="fn()">工具函数请求数据button>
- <script>
- function fn(){
- tool("/news",function(str){
- //将网络请求到的数据用于业务中(写页面)
- var obj = JSON.parse(str)
- for (let i = 0; i < obj.data.length; i++) {
- console.log(obj.data[i],1111)
- let box = document.createElement("div")
- box.className = "box"
- box.innerHTML = `${obj.data[i].title}---${obj.data[i].content}`
- document.body.appendChild(box)
- }
- })
- }
- script>
工具文件 tool.js
- function tool(url, cb) {
- //封装Ajax网络请求代码
- var xhr = new XMLHttpRequest() || new ActiveXObject("Microsoft.XMLHTTP")
- xhr.open("GET", url, true)
- xhr.send()
- xhr.onreadystatechange = function() {
- if (xhr.readyState == 4 && xhr.status == 200) {
- //将请求到的数据传给cb回调函数执行业务
- cb(xhr.responseText)
- }
- }
- }
后端index.js注册网址并写入数据
- var router=require("./router.js")
- router.get("/news",function(req,res){
- var obj={data:[{title:"新闻1",content:"内容1",id:1},
- {title:"新闻2",content:"内容2",id:2},
- {title:"新闻3",content:"内容3",id:3}
- ]}
- var str=JSON.stringify(obj)
- res.setHeader("content-Type","text/json;charset=utf8")
- res.end(str)
- })
- router.get("/author",function(req,res){
- var obj=[{name:"lily",id:1},
- {name:"lucy",id:2},
- {name:"jack",id:3}
- ]
- var str=JSON.stringify(obj)
- res.setHeader("content-Type","text/json;charset=utf8")
- res.end(str)
- })
请求结果:

用回调函数封装Ajax需要自己设计tool函数,而通过jquery只需要一个引入一个jquery框架就可以实现以上效果
准备工作:引入jquery标签 
修改以上代码:
1、弃用tool.js
2、将 替换为
3、将tool函数名 替换为 $.get
前端author.html文件请求数据:(index.html同理)
- <script src="https://lf9-cdn-tos.bytecdntp.com/cdn/expire-1-M/jquery/2.2.4/jquery.js">script>
- <button onclick="fn()">用jQuery请求数据button>
- <script>
- function fn() {
- $.get("/author", function(res) {
- console.log(res)
- })
- }
- script>
请求结果:

ajax请求回调地狱
- <h1>promise封装ajaxh1>
- <script>
- function fn() {
- $.get("/ajax1", (res1) => {
- console.log(res1, JSON.parse(res1), 1)
- $.get("/ajax2", (res2) => {
- console.log(res2, JSON.parse(res2), 2)
- $.get("/ajax3", (res3) => {
- console.log(res3, JSON.parse(res3), 3)
- $.get("/ajax4", (res4) => {
- console.log(res4, JSON.parse(res4), 4)
- })
- })
- })
- })
- }
- script>
promise语法:
(1) promise:
Promise是一个 构造函数, 用于创建Promise对象
Promise对象:可以理解为一个处理异步操作的容器
(2) promise对象的三个状态.:
- pending(进行中)
- fulfilled (已成功)
- rejected(已失败)
- 只有异步操作的结果可以决定当前是哪一种状态 任何其他操作都无法改变这个状态
(3) promise对象的状态改变:
- 从pending变为fulfilled 此时应该执行 resolve()
- 从pending变为rejected 此时应该执行 reject()
- 一旦状态改变,就不会再变,任何时候都可以得到这个结果
- resolve() 和 reject() 只能执行一个
注:promise本质不是控制 异步代码的执行顺序,而是控制异步代码结果处理的顺序
(4) 使用:
1.实例化Promise对象 : 将异步操作放入Promise中
- resolve:异步操作 成功状态
- reject : 异步操作 失败状态
2.调用then() 方法: 处理异步操作结果
promise对象.then((data)=>{ 处理成功数据 },(err)=>{ 处理失败信息 })
promise静态方法:(常见于笔试题中)
- Promise.resolve():将现有对象转为 Promise 对象
var p1=Promise.resolve(200)//传入的数据 封装成产生正确数据的Promise对象 console.log(p1) //200 p1.then((data)=>console.log(data)) //等同于 var p1=new Promise((resolve,reject)=>{ resolve(200) }) p1.then((data)=>console.log(data))
- Promise.reject():返回一个新的 Promise 实例 该实例的状态为
rejected
var p3=Promise.reject(200) //传入的数据 封装成产生错误数据的Promise对象 console.log(p3) //200 p3.catch(e=>console.log(e)) //200
- Promise.all():用于将多个 Promise 实例,包装成一个新的 Promise 实例
var p1=new Promise((n1,n2)=>{ $.get("/ajax1",(data)=>{ n1(data) }) }) var p2=new Promise((n1,n2)=>{ $.get("/ajax2",(data)=>{ n1(data) }) }) var p3=new Promise((n1,n2)=>{ $.get("/ajax3",(data)=>{ n1(data) }) }) var p=Promise.all([p1,p2,p3]) p.then((arr)=>{ conosle.log(arr) }) /*只有当三个promise对象的状态都为fulfilled,p的状态才会变为fulfilled 此时p1,p2,p3的返回值组成一个数组,传递给p的回调函数 */ /*只要有一个promise对象被rejected,p的状态就会变成rejected 此时第一个被rejected的实例的返回值会传递给p的回调函数 */
原理 :
在then方法中返回一个promise对象
- 链式嵌套,需在上一个promise对象的then方法中返回下一个promise对象进而实现连调
解决上述异步回调地狱(回调函数层次嵌套)的问题
- function myaxios(url) {
- return new Promise((resolve, reject) => {
- //封装ajax
- try {
- //try里的代码3种情况: 语法错误|语法正确但产生错误的业务数据|正确的业务数据
- let xhr = new XMLHttpRequest() || ActiveXObject("xxx")
- xhr.open("GET", url, true)
- xhr.send()
- xhr.onreadystatechange = function () {
- if (xhr.readyState == 4) {
- console.log(123)
- if (xhr.status == 200) {
- resolve(xhr.responseText)
- } else if (xhr.status == 404) {
- reject(xhr.responseText)
- } else {
- reject("net err")
- }
- }
- }
- } catch (e) {
- reject(xhr.responseText)
- }
- })
- }
- var p1 = myaxios('/ajax')
- p1.then((data1) => {
- console.log(data1)
- return myaxios('/ajax1')
- })
- .then((data2) => {
- console.log(data2)
- return myaxios('/ajax2')
- })
- .then((data3) => {
- console.log(data3)
- return myaxios('/ajax3')
- })
- .then((data4) => {
- console.log(data4)
- })
- .catch((e) => {
- console.log(e)
- })
- var p1=axios('/ajax')
- p1.then((data1)=>{
- console.log(data1.data)
- return axios('/ajax1')
- })
- .then((data2)=>{
- console.log(data2.data)
- return axios('/ajax2')
- })
- .then((data3)=>{
- console.log(data3.data)
- return axios('/ajax3')
- })
- .then((data4)=>{
- console.log(data4.data)
- })
- .catch((e)=>{
- console.log(e)
- })
示例:
- // 直接请求ajax1
-
- var res=fetch("/ajax1")
- //res是一个promise对象 这个对象内部有后端传过来的二进制包
- res.then((data)=>{
- return data.json() //调用函数解二进制包
- })
- .then((result)=>{
- console.log(result)
- })
写得很详细的一个博主的文章:
原文链接:https://blog.csdn.net/qq_43539854/article/details/125053587
async语法
(1)函数前面使用async修饰
(2)函数内部:promise操作使用await修饰 await代替then方法取数据
- await 后面是promise对象, 左侧的返回值就是这个promise对象的then方法中的结果
- await 只能取出正确的数据
- await 必须要写在async修饰的函数中,不能单独使用,否则程序会报错
- await 是遍历器的语法糖
终极高内聚低耦合
- let data1=await new Promise((n1,n2)=>{n1(2000)})
- console.log(data1) //打印2000
-
- let data2=await axios('/ajax2')
- console.log(data2)
-
- let data3=await axios('/ajax3')
- console.log(data3)
-
- let data4=await axios('/ajax4')
- console.log(data4)