Vue第三天学习总结—— Vue全家桶之前后端交互(前后的交互模式、Promise用法、接口调用-fetch用法、接口调用-axios用法、接口调用-async/await用法 )

(一) 前后的交互模式

  • 之前处理的案例都是静态数据,而真正的项目都是需要后台提供真正的数据的
  • 那么前台就需要通过后台提供的数据接口获取数据

1. 接口调用方式

  • 原生ajax:比较麻烦,一般不用
  • 基于jQueryajax:这个会简单点,但jquery侧重DOM操作,而Vue很少涉及DOM操作
  • fetch:ajax升级版,标准化组织制定的一套新规范
  • axios:第三方的库,比fetch更加强大

客户端与服务器通信方式

在这里插入图片描述

  • 左侧为客户端,右侧为服务器
  • 客户端通过互联网向服务器发起请求(寻求页面,数据)
  • 服务器通过互联网向客户端做出响应(返回页面,数据)

2. Url地址格式

  • urlUniform Resource Locator,统一资源定位符,我们理解为地址即可
  • 通过url可以获取对应的资源或数据

2.1 传统形式的URL

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

  • schema:协议。例如http、https、ftp等
  • host:域名或者IP地址
  • port:端口,http默认端口80,可以省略
  • path:路径,例如/abc/a/b/c
  • query:查询参数,例如uname=lisi&age=12
  • fragment:锚点(哈希Hash),用于定位页面的某个位置

符合规则的URL

  • http://www.itcast.cn
  • http://www.itcast.cn/java/web
  • http://www.itcast.cn/java/web?flag=1
  • http://www.itcast.cn/java/web?flag=1#function

2.2Restful形式的url

Restful是定义url的一种规则。目前公司内部使用Restful设计风格的url比较多

Restful形式的url,如果要通过url传递参数,不是 拼接,而是直接以 /拼接即可

HTTP请求方式

  • GET 查询
  • POST 添加
  • PUT 修改
  • DELETE删除

符合规则的URL地址

  • http://www.hello.com/books GET
  • http://www.hello.com/books POST
  • http://www.hello.com/books/123 PUT
  • http://www.hello.com/books/123 DELETE

根据请求方式,来确定具体操作是增删改查哪种

第一个url和第二个url是一样的,但是请求方式不一样

  • get代表获取图书列表
  • post代表新增图书数据,并且会通过请求体传递新增图书的数据

第三个url代表要更新id为123的图书信息,更新的图书数据通过请求体传递

(二) Promise用法

1. 异步调用

  • 如果是要发起请求,访问接口获取数据,因为这个过程是比较耗时的,所以需要异步

1.1 异步效果分析(以下均是异步)

定时任务

setTimeout(function(){
   },10000)

事件函数

xxx.addEventListener('click',function(){
   })
xxx.onclick=function(){
   } // 即使这里的function不是回调函数,但也是异步

只要是回调函数就是异步:(函数作为参数传递的都是回调函数)

Ajax

<body>
  <div>前后端交互</div>
  <script type="text/javascript" src="js/jquery.js"></script>
  <script type="text/javascript">
    /*
      前后端交互-异步编程与Promise概述
    */
    var ret = '---';
    $.ajax({
     
      url: 'http://localhost:3000/data',//接口返回HelloWorld
      success: function(data) {
     
        ret = data;
        console.log(ret)//这里可以拿到HelloWorld
      }
    });
    console.log(ret)//这里是没有办法拿到HelloWorld,因为ajax发起请求是异步的
    </script>
 <body>
在/myapi 文件夹中 的index.js 运行node

先输入 npm i 
再输入 nodemon index.js

- index.js中有/data路由,并且返回Hello World!数据
- 服务运行在3000端口
- 终端进入myapi目录之后,运行nodemon index.js
- nodemon可以检测代码修改,自动重启服务

1.2 多次异步调用的依赖分析

多次异步调用的结果顺序不确定

第一步:发起三次请求,观察结果:

$.ajax({
   
     url: 'http://localhost:3000/data',
     success: function(data) {
   
         console.log(data)
     }
 });
$.ajax({
   
    url: 'http://localhost:3000/data1',
    success: function(data) {
   
        console.log(data)
    }
});
$.ajax({
   
    url: 'http://localhost:3000/data2',
    success: function(data) {
   
        console.log(data)
    }
});

第二步: 修改后台

在在/myapi 文件夹中 的index.js 添加data1和data2路由

// 路由
app.get('/data', (req, res) => {
   
    res.send('Hello World!')
})
app.get('/data1', (req, res) => {
   
    setTimeout(function() {
   
        res.send('Hello TOM!')
    }, 1000);
})
app.get('/data2', (req, res) => {
   
    res.send('Hello JERRY!')
})

第三步:在浏览器中打开——效果

在这里插入图片描述

这个打印的顺序不不固定的,而是根据网络状态而定

虽然这次看到的结果,跟咱们发起请求的代码顺序一致,但是下次就可能不一定了

异步调用结果如果存在依赖需要嵌套

如果我们需要在data请求成功之后再请求data1,然后需要在data1请求成功之后再请求data2,代码如下:

 $.ajax({
   
     url: 'http://localhost:3000/data',
     success: function(data) {
   
         console.log(data)
         $.ajax({
   
             url: 'http://localhost:3000/data1',
             success: function(data) {
   
                 console.log(data)
                 $.ajax({
   
                     url: 'http://localhost:3000/data2',
                     success: function(data) {
   
                         console.log(data)
                     }
                 });
             }
         });
     }
 });

完整代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>

<body>
    <div>前后端交互</div>
    <script type="text/javascript" src="js/jquery.js"></script>
    <script type="text/javascript">
        //前后端交互-异步编程与Promise概述

        var ret = '---';
        $.ajax({
     
            url: 'http://localhost:3000/data',
            success: function(data) {
     
                ret = data;
                console.log(ret)
            }
        });
        console.log(ret)

        // ----------------------------

        // $.ajax({
     
        //   url: 'http://localhost:3000/data',
        //   success: function(data) {
     
        //     console.log(data)
        //   }
        // });
        // $.ajax({
     
        //   url: 'http://localhost:3000/data1',
        //   success: function(data) {
     
        //     console.log(data)
        //   }
        // });
        // $.ajax({
     
        //   url: 'http://localhost:3000/data2',
        //   success: function(data) {
     
        //     console.log(data)
        //   }
        // });

        // -----------------------------------
        
        $.ajax({
     
            url: 'http://localhost:3000/data',
            success: function(data) {
     
                console.log(data)
                $.ajax({
     
                    url: 'http://localhost:3000/data1',
                    success: function(data) {
     
                        console.log(data)
                        $.ajax({
     
                            url: 'http://localhost:3000/data2',
                            success: function(data) {
     
                                console.log(data)
                            }
                        });
                    }
                });
            }
        });
    </script>
</body>

</html>

上述代码的层级太深,可读性比较糟糕,可以用Promise来解决

2. Promise概述

Promise是异步编程的一种解决方案,从语法上讲,Promise是一个对象,从它可以获取异步操作的消息。

使用Promise主要有以下好处:

  • 可以避免多层异步调用嵌套问题(回调地狱)
  • Promise对象提供了简洁的API,使得控制异步操作更加容易

网址:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise

Promise总结:就是处理异步逻辑的一个工具

3. Promise基本用法

  • 实例化Promise对象,构造函数中传递函数,该函数中用于处理异步任务
  • resolvereject两个参数用于处理成功和失败两种情况,并通过p.then获取处理结果
var p = new Promise(function(resolve , reject) {
   
    // 成功时调用 resolve()
    // 失败时调用 reject()
    
});
p.then(function(ret) {
   
    // 从 resolve 得到正常结果
} , function(ret) {
   
    // 从 reject 得到错误信息
});

resolve:解决,理解:解决了,就是成功了

reject:拒绝,理解:被决绝了,就是失败了

then:请求结束之后,不管成功失败都会调用then方法

  • 它最多需要有两个参数:Promise 的成功和失败情况的回调函数
  • then:然后,接下来。理解:请求结束,接下来处理结果

示例代码:

我们先让Promise处理一下setTimeout这种异步逻辑:
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>

<body>

  <script type="text/javascript">
    /*
      Promise基本使用
    */
    console.log(typeof Promise)
    console.dir(Promise);

    var p = new Promise(function (resolve, reject) {
     
      // 这里用于实现异步任务
      setTimeout(function () {
     
        var flag = false;
        if (flag) {
     
          // 正常情况
          resolve('hello');
        } else {
     
          // 异常情况
          reject('出错了');
        }
      }, 100);
    });
    p.then(function (data) {
       //data接收resolve传递过来的hello
      console.log(data) //如果flag为true,输出hello
    }, function (info) {
      //info接收reject传递过来的出错了
      console.log(info) //如果flag为false,输出出错了
    });
  </script>
</body>

</html>

4. 基于Promise处理Ajax请求并处理回调地狱问题

4.1 处理原生Ajax

XMLHttpRequestAjax的核心,Ajax内部就是通过XMLHttpRequest来发起请求的

// Promise如何处理XMLHttpRequest这个异步逻辑
function queryData(){
   
    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' , '/data');
        xhr.send(null);
    })
}

queryData('http://localhost:3000/data')
      .then(function (data) {
   
        console.log(data);
      }, function (info) {
   
        console.log(info);
      });
  • onreadystatechange是捕获请求的状态码,只要状态码发生变化就会调用
    • 我们不关心状态不为4的,所以如果readyState不等于4直接返回
    • 4是请求操作已经完成,意思就是请求完成之后,在执行以下逻辑
    • status:是响应状态码,如果为200说明成功
    • responseText是收到的响应数据
  • open初始化请求:请求方式,url
  • send:发起请求,null代表请求体(get不需要请求体)

4.2 发送多次Ajax请求

queryData()
 .then(function(data){
   
      return queryData();
  })
 .then(function(data){
   
      return queryData();
  })
 .then(function(data){
   
      return queryData();
  })
       
  • queryData返回了一个Promise对象,所以可以调用then方法
  • then方法又返回了queryData方法的调用,相当于又返回了一个Promise对象,所以可以接着调用then方法

示例代码

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>

<body>

  <script type="text/javascript">
    /*
      基于Promise发送Ajax请求
    */
    function queryData(url) {
     
      var p = new Promise(function(resolve, reject){
     
        var xhr = new XMLHttpRequest();
        xhr.onreadystatechange = function(){
     
          if(xhr.readyState != 4) return;  //请求状态不等于4,说明异常
          if(xhr.readyState == 4 && xhr.status == 200) {
     
            // 处理正常的情况
            resolve(xhr.responseText);
          }else{
     
            // 处理异常情况
            reject('服务器错误');
          }
        };
        xhr.open('get', url); //初始化请求
        xhr.send(null); //发送请求
      });
      return p;
    }

    // queryData('http://localhost:3000/data')
    //   .then(function(data){
     
    //     console.log(data);
    //   },function(info){
     
    //     console.log(info)
    //   });

    // ============================
    // 发送多个ajax请求并且保证顺序
    queryData('http://localhost:3000/data')
      .then(function(data){
       //data请求结束之后调用
        console.log(data)
        return queryData('http://localhost:3000/data1');  //然后查询data1
      })
      .then(function(data){
       //data1请求结束之后调用
        console.log(data);
        return queryData('http://localhost:3000/data2');  //最后查询data2
      })  
      .then(function(data){
       //data2请求结束之后调用
        console.log(data)
      });
  </script>
</body>

</html>

总结:想要确保发送多个ajax请求并且保证顺序,就需要在上一个请求结束之后的then中发送第二个请求

5.Promisethen方法参数中的函数返回值

then方法的参数是一个回调函数,而这个回调函数是有返回值的

返回值有两种情况:

  • 返回Promise实例对象:返回的该实例对象会调用下一个then
  • 返回普通值:返回的普通值会直接传递给下一个then,通过then参数中函数的参数接收该值

5.1 返回Promise实例对象

返回的该实例对象会调用下一个then

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>

<body>

  <script type="text/javascript">
    /*
      then参数中的函数返回值
    */
    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);
      });
    }
    queryData('http://localhost:3000/data')
      .then(function (data) {
     
        return queryData('http://localhost:3000/data1')
      })
      .then(function (data) {
     
        return new Promise(function (resolve, reject) {
     
          setTimeout(function () {
     
            resolve(123);
          }, 1000)
        })
      })     
      .then(function (data) {
     
        console.log(data); // 123
      }) 
  
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值