一、前后端交互模式:

1. 接口调用方式:

  • 原生ajax
  • 基于jQuery的ajax
  • fetch Api;
  • axios 库;

2. url地址格式:

2.1 传统形式的url:

schema://host:port/path?query#fragment

2.2 restful形式的url:

  • get;
  • post;
  • put;
  • delete;

二、异步:

  • JavaScript的执行环境是「单线程」;
  • 所谓单线程,是指JS引擎中负责解释和执行JavaScript代码的线程只有一个,也就是一次只能完成一项任务,这个任务执行完后才能执行下一个,它会「阻塞」其他任务。这个任务可称为主线程;
  • 异步模式可以一起执行多个任务;
  • JS中常见的异步调用:
    • 定时任何
    • ajax
    • 事件函数

二、promise用法:

1. 什么是promise:

  • promise是异步编程的一种解决方案, 从语法上讲, promise是一个对象, 从它可以获取异步操作的消息;
  • 使用promise主要有以下好处:
    • 可以避免多层异步嵌套问题(回调地狱);
    • promise对象提供了简洁的API, 是的控制异步操作更加容易;

2. promise基本用法:

  • 实例化Promise对象, 构造函数中传递函数, 该函数用于处理异步任务;
  • resolve和reject两个参数用于处理成功赫尔失败两种情况, 并通过p.then获取处理结果;
<script type="text/javascript">
   var p = new Promise(function(resolve, reject){
     //这里用于实现异步任务  setTimeout
     setTimeout(function(){
       var flag = false;
       if(flag) {
         //3. 正常情况
         resolve('hello');
       }else{
         //4. 异常情况
         reject('出错了');
       }
     }, 100);
   });
   // Promise实例生成以后,可以用then方法指定resolved状态和reject状态的回调函数 
   // 在then方法中,你也可以直接return数据而不是Promise对象,在后面的then中就可以接收到数据了  
   p.then(function(data){
     console.log(data)
   },function(info){
     console.log(info)
   });
 </script>

3. 基于Promise发送Ajax请求:

<script type="text/javascript">
  /*
    基于Promise发送Ajax请求
  */
  function queryData(url) {
   // 创建一个Promise实例
    var p = new Promise(function(resolve, reject){
      var xhr = new XMLHttpRequest();
      xhr.onreadystatechange = function(){
        if(xhr.readyState != 4) return;
        if(xhr.readyState == 4 && xhr.status == 200) {
          // 处理正常的情况
          resolve(xhr.responseText);
        }else{
          // 处理异常情况
          reject('服务器错误');
        }
      };
      xhr.open('get', url);
      xhr.send(null);
    });
    return p;
  }
	// 注意:  这里需要开启一个服务 
  	// 在then方法中,你也可以直接return数据而不是Promise对象,在后面的then中就可以接收到数据了
  queryData('http://localhost:3000/data')
    .then(function(data){
      console.log(data)
      // 1.4 想要继续链式编程下去 需要 return  
      return queryData('http://localhost:3000/data1');
    })
    .then(function(data){
      console.log(data);
      return queryData('http://localhost:3000/data2');
    })
    .then(function(data){
      console.log(data)
    });
</script>

4. promise基本API:

4.1 实例方法:

方法说明
.then()得到异步任务正确的结果
.catch()获取异常信息
.finally()成功与否都会执行(不是正式标准)
<script type="text/javascript">
  /*
    Promise常用API-实例方法
  */
  // console.dir(Promise);
  function foo() {
    return new Promise(function(resolve, reject){
      setTimeout(function(){
        // resolve(123);
        reject('error');
      }, 100);
    })
  }
  // foo()
  //   .then(function(data){
  //     console.log(data)
  //   })
  //   .catch(function(data){
  //     console.log(data)
  //   })
  //   .finally(function(){
  //     console.log('finished')
  //   });

  // --------------------------
  // 两种写法是等效的
  foo()
    .then(function(data){
      // 得到异步任务正确的结果
      console.log(data)
    },function(data){
      // 获取异常信息
      console.log(data)
    })
    // 成功与否都会执行(不是正式标准) 
    .finally(function(){
      console.log('finished')
    });
</script>

4.1 对象方法:

方法说明
.all()Promise.all方法接受一个数组作参数,数组中的对象(p1、p2、p3)均为promise实例(如果不是一个promise,该项会被用Promise.resolve转换为一个promise)。它的状态由这三个promise实例决定
.race()Promise.race方法同样接受一个数组作参数. 当p1, p2, p3中有一个实例的状态发生改变(变为fulfilled或rejected), p的状态就跟着改变。并把第一个改变状态的promise的返回值,传给p的回调函数
<script type="text/javascript">
  /*
    Promise常用API-对象方法
  */
  // console.dir(Promise)
  function queryData(url) {
    return new Promise(function(resolve, reject){
      var xhr = new XMLHttpRequest();
      xhr.onreadystatechange = function(){
        if(xhr.readyState != 4) return;
        if(xhr.readyState == 4 && xhr.status == 200) {
          // 处理正常的情况
          resolve(xhr.responseText);
        }else{
          // 处理异常情况
          reject('服务器错误');
        }
      };
      xhr.open('get', url);
      xhr.send(null);
    });
  }

  var p1 = queryData('http://localhost:3000/a1');
  var p2 = queryData('http://localhost:3000/a2');
  var p3 = queryData('http://localhost:3000/a3');
   Promise.all([p1,p2,p3]).then(function(result){
     // all 中的参数  [p1,p2,p3]   和 返回的结果一 一对应["HELLO TOM", "HELLO JERRY", "HELLO SPIKE"]
     console.log(result) //["HELLO TOM", "HELLO JERRY", "HELLO SPIKE"]
   })
   
  Promise.race([p1,p2,p3]).then(function(result){
    // 由于p1执行较快,Promise的then()将获得结果'P1'。p2,p3仍在继续执行,但执行结果将被丢弃。
    console.log(result) // "HELLO TOM"
  })
</script>

三、fetch Api:

1. fetch概述:

1.1 基本特性:

  • 更加简单的数据获取方式, 功能更强大, 更灵活, 可以看做xhr的升级版;
  • 基于promise;

1.2 语法结构:

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

2. fetch基本用法:

  <script type="text/javascript">
    /*
      Fetch API 基本用法
      	fetch(url).then()
     	第一个参数请求的路径   Fetch会返回Promise   所以可以使用then 拿到请求成功的结果 
    */
    fetch('http://localhost:3000/fdata').then(function(data){
      // text()方法属于fetchAPI的一部分,它返回一个Promise实例对象,用于获取后台返回的数据
      return data.text();
    }).then(function(data){
      //   在这个then里面能拿到最终的数据  
      console.log(data);
    })
  </script>

3. fetch请求参数:

3.1 参数形式

  • method(string): http请求方法(POST,GET,DELETE,UPDATE,PATCH和PUT), 默认是GET;
  • body(string): http的请求参数;
  • headers(obj): http请求头, 默认为{}

3.2 传统方式:GET传参

// GET参数传递 - 传统URL  通过url  ? 的形式传参 
fetch('http://localhost:3000/books?id=123', {
	// get 请求可以省略不写 默认的是GET 
    method: 'get'
})
.then(function(data) {
	// 它返回一个Promise实例对象,用于获取后台返回的数据
    return data.text();
}).then(function(data) {
	// 在这个then里面能拿到最终的数据  
    console.log(data)
});

3.3 restful形式: GET传参

// GET参数传递  restful形式的URL  通过/ 的形式传递参数  即  id = 456 和id后台的配置有关   
fetch('http://localhost:3000/books/456', {
	// get 请求可以省略不写 默认的是GET 
    method: 'get'
})
.then(function(data) {
    return data.text();
}).then(function(data) {
    console.log(data)
});

3.4 delete:

// DELETE请求方式参数传递      删除id  是  id=789
fetch('http://localhost:3000/books/789', {
     method: 'delete'
 })
 .then(function(data) {
     return data.text();
 }).then(function(data) {
     console.log(data)
 });

3.5 POST请求传参

// 1. 字符串body传参
fetch('http://localhost:3000/books', {
    method: 'post',
	// 传递数据 
    body: 'uname=lisi&pwd=123',
	// 设置请求头 
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded'
    }
})
.then(function(data) {
    return data.text();
}).then(function(data) {
    console.log(data)
});

// 2. json body传参
fetch('http://localhost:3000/books', {
    method: 'post',
    body: JSON.stringify({
        uname: '张三',
        pwd: '456'
    }),
    headers: {
        'Content-Type': 'application/json'
    }
})
.then(function(data) {
    return data.text();
}).then(function(data) {
    console.log(data)
});

3.5 put请求传参:

fetch('http://localhost:3000/books/123', {
  method: 'put',
   body: JSON.stringify({
       uname: '张三',
       pwd: '789'
   }),
   headers: {
       'Content-Type': 'application/json'
   }
})
.then(function(data) {
   return data.text();
}).then(function(data) {
   console.log(data)
});

4. fetchAPI 中 响应格式

  • 用fetch来获取数据,如果响应正常返回,首先看到的是一个response对象,其中包括返回的一堆原始字节,这些字节需要在收到后,需要通过调用方法将其转换为相应格式的数据,比如JSON,BLOB或者TEXT等等;
fetch('http://localhost:3000/json').then(function(data){
  //return data.text(); //  //  将获取到的数据 转换成字符串 
  
  return data.json();   //  将获取到的数据使用 json 转换对象 
}).then(function(data){
  // console.log(typeof data)
  //var obj = JSON.parse(data);
  // console.log(data.uname)
  console.log(obj.uname,obj.age,obj.gender)
})

四、axios API:

1. 什么是axios:

  • 基于promise用于浏览器和node.js的http客户端;
  • 支持浏览器和node.js;
  • 支持promise;
  • 能拦截请求和响应;
  • 自动转换json数据;
  • 能转换请求和响应数据;

2. axios基础用法:

axios.get('/adata')
	 .then(ret => {
	 // data属性名称是固定的, 用于获取后台响应的数据;
	 console.log(ret.data);
	 })

2.1 axios的get请求:

  • 通过传统的url传参:
axios.get('/adata?id=123')
	  .then(ret => {
		console.log(rest.data)
	  })
  • restful 形式传递参数:
axios.get('/adata/123')
	  .then(ret => {
		console.log(ret.data)
	  })
  • 通过params 形式传递参数:
axios.get('/adata', {
	params: {
		id: 123
	}
}).then(ret => {
	console.log(ret.data)
})

2.2 axios的delete请求:

  • 通过传统的url传参:
axios.delete('/adata?id=123')
	  .then(ret => {
		console.log(rest.data)
	  })
  • restful 形式传递参数:
axios.delete('/adata/123')
	  .then(ret => {
		console.log(ret.data)
	  })
  • 通过params 形式传递参数:
axios.delete('/adata', {
	params: {
		id: 123
	}
}).then(ret => {
	console.log(ret.data)
})

2.3 axios的post请求:

  • 过选项传递参数(json提交)
axios.post('/adata', {
  uname: 'lisi',
  pwd: 123
}).then(function(ret){
  console.log(ret.data)
})
  • 通过 URLSearchParams 传递参数(表单提交):
var params = new URLSearchParams();
params.append('uname', 'zhangsan');
params.append('pwd', '111');
axios.post('/adata', params)
	  .then(function(ret){
		  console.log(ret.data)
	  })

2.4 axios的put请求:

  • 过选项传递参数(json提交)
axios.put('/adata', {
  uname: 'lisi',
  pwd: 123
}).then(function(ret){
  console.log(ret.data)
})
  • 通过 URLSearchParams 传递参数(表单提交):
var params = new URLSearchParams();
params.append('uname', 'zhangsan');
params.append('pwd', '111');
axios.put('/adata', params)
	  .then(function(ret){
		  console.log(ret.data)
	  })

3. axios的响应结果:

3.1 响应结果的主要属性:

  • data: 实际响应的数据;
  • headers: 响应头信息;
  • status: 响应状态码;
  • statusText: 响应状态信息;

4. axios全局配置:

//  配置公共的请求头 
axios.defaults.baseURL = 'https://api.example.com';
//  配置 超时时间
axios.defaults.timeout = 2500;
//  配置公共的请求头
axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
// 配置公共的 post 的 Content-Type
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';

5. axios 拦截器:

5.1 请求拦截器:

  • 请求拦截器的作用是在请求发送前进行一些操作
    • 例如在每个请求体里加上token,统一做了处理如果以后要改也非常容易
axios.interceptors.request.use(function(config) {
     console.log(config.url)
     // 任何请求都会经过这一步   在发送请求之前做些什么   
     config.headers.mytoken = 'nihao';
     // 这里一定要return   否则配置不成功  
     return config;
   }, function(err){
      //  对请求错误做点什么    
     console.log(err)
   })

5.2 响应拦截器:

在这里插入图片描述

  • 响应拦截器的作用是在接收到响应后进行一些操作
    • 例如在服务器返回登录状态失效,需要重新登录的时候,跳转到登录页
axios.interceptors.response.use(function(res) {
 //  在接收响应做些什么  
  var data = res.data;
  return data;
}, function(err){
  //  对响应错误做点什么  
  console.log(err);
})

五、async 和 await:

1. async / await:

  • async / awai是ES7引入的新语法, 可以实现更加方便的异步操作;
  • async作为一个关键字放到函数前面:
    • 任何一个async函数都会隐式返回一个promise;
  • await关键字只能在使用async定义的函数中使用:
    ​ - await后面可以直接跟一个 Promise实例对象;
    ​ - await函数不能单独使用;

2. async基础用法:

// async作为一个关键字放到函数前面
async function queryData() {
 //  await关键字只能在使用async定义的函数中使用 await后面可以直接跟一个 Promise实例对象
 var ret = await new Promise(function(resolve, reject){
   setTimeout(function(){
     resolve('nihao')
   },1000);
 })
 // console.log(ret.data)
 return ret;
}
//  任何一个async函数都会隐式返回一个promise 可以使用then 进行链式编程
queryData().then(function(data){
 console.log(data)
})

3. async函数处理多个异步函数:

axios.defaults.baseURL = 'http://localhost:5000';

async function queryData() {
 //  添加await之后 当前的await 返回结果之后才会执行后面的代码   
  var info = await axios.get('async1');
  //  让异步代码看起来、表现起来更像同步代码
  var ret = await axios.get('async2?info=' + info.data);
  return ret.data;
}

queryData().then(function(data){
  console.log(data)
})
Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐