AJAX

浅谈AJAX

一、ajax初步

AJAX

  • Asynchronous javascript and xml 异步的 javascript 和 xml
  • 数据都是存储数据库中的。而服务端通过服务端的技术(nodejs、php、java、python…)把数据从数据库中读取出来再处理成客户端需要的数据,然后通过网络技术(ajax、jsonp 等)把数据传递给客户端;

ajax 四步

第一步:创建一个ajax对象
var xhr = new XMLHttpRequest();

第二步:调用ajax对象的open方法设置请求信息:
xhr.open('GET', './data.json', false);

参数详解:

  • 请求方式 http method(GET POST PUT DELETE OPTIONS…)
  • 请求的服务端 url 地址(接口)
  • 同步或异步 true 表示同步,false 表示异步

第三步:设置xhr的onreadystatechange事件监听
xhr.onreadystatechange = function () {
    if (xhr.readyState === 4 && xhr.status === 200) {
        // 当xhr.readyState变成4 并且 xhr 的 status 为200时表示当前请求成功
        // 当成功后,xhr 的 responseText 属性会存储着本次请求获取的数据
        console.log(xhr.responseText);
    }
};

第四步:发送请求
xhr.send();

jequry的AJAX

// ajax 方法是 jQ 的静态方法;ajax 定义在 jQ 自己身上,没有定义在原型上,只有 jQuery 自己能调用

$.ajax({
  url: 'json/data.json', // 接口
  method: 'GET', // http method 请求方式,默认'GET'
  async: true, // 是否异步,默认值 true,表示异步;
  dataType: 'json', // 数据类型,因为 jq 的 ajax 帮我们格式化数据,所以告诉它数据类型
  data: {
    id: '17',
    price: 1000
  }, // POST 请求的参数,是发送给服务器的数据
  success (data) {
    // 如果 ajax 请求成功会调用这个函数;这个 data 就是请求回来的数据,并且jq会帮我们处理成对象,不
    // 用我们再 JSON.parse()
    console.log(data);
  },
  error (err) { 
    // 如果 ajax 请求失败,会调用这个函数
    console.log(err);
  }
});
---------------------------------------------------------------
  let send = () => {
    //请求数据并绑定
    $.ajax({
        url: "banner.json", //请求路径
        type: "get",
        async: false,
        success: function (data) {
            bindHtml(data);
            timer = setInterval(autoMove, 2000)
            changeTip();

        }
    })
}

二、数据绑定

  • 页面中的数据通常都不是写死的,大多数情况下都需要动态绑定数据;
let ul = document.getElementById('ul');
var ary = [
    {
        name: '张三',
        age: 18
    },
    {
        name: '李四',
        age: 19
    },
    {
        name: '王五',
        age: 20
    }
];

1. 创建元素

利用动态创建 DOM 的方法,动态创建 dom 对象

for (let i = 0; i < ary.length; i++) {
    let cur = ary[i];
    let newLi = document.createElement('li');
    newLi.innerHTML = 'name: ' + cur.name + ' age:' + cur.age;
    ul.appendChild(newLi); // 所以在这里每次都插入一个新元素,就会引发一次 DOM 回流,性能开销很大,
    // 不推荐这种做法
}
  • DOM回流(reflow): 在页面中某个元素的插入、删除、位置、大小发送变化,那么会重新计算其他元素的位置,这样做非常消耗性能;
  • DOM重绘(repaint):当页面中的元素的背景、字体颜色发送改变、那么浏览器需要对其进行重新绘制,这种现象称为重绘;

2. 利用文档碎片

文档碎片:一个通过 DOM api 创建的临时存放 DOM 元素的容器

let frg = document.createDocumentFragment(); // 创建文档碎片
for (let i = 0; i < ary.length; i++) {
    let cur = ary[i];
    let newLi = document.createElement('li');
    newLi.innerHTML = 'name: ' + cur.name + ' age:' + cur.age;
    frg.appendChild(newLi);
}
ul.appendChild(frg);
frg = null; // 当插入后,手动释放 frg 的内存(手动释放临存储对象的内存是一种优秀的编程习惯)

3. 拼接字符串+innerHTML(元素对象的innerHTML可以识别字符串中的html标签)
let str = '';
for (let i = 0; i < ary.length; i++) {
    let cur = ary[i];
    str += '<li>' + 'name: ' + cur.name + 'age: ' + cur.age + '</li>';
}
console.log(str);
ul.innerHTML = str;

4. 模板字符串
let tpl = ``;
for (let i = 0; i < ary.length; i++) {
    let cur = ary[i];
    tpl += `<li>
                         <strong>name: ${cur.name}</strong>
                          <strong>age: ${cur.age}</strong>
                        </li>`
}
ul.innerHTML = tpl;

AJAX深入理解

一、什么是AJAX

ajax: async javascript and xml 异步的 js 和 xml,此处的异步指的是:局部刷新(对应的是全局刷新)
ajax : 是一种前后端数据交互的技术;
前后端同时进行开发项目;数据交互;接口文档:url 请求方式,参数,返回的数据类型,返回数据格式;

1. 服务器端如何渲染

当服务器接收到请求后:

  1. 找到对应的页面,获取到页面的代码
  2. 根据需求从数据库中获取到需要动态展示的数据
  3. 把页面和数据混合在一起进行渲染,生成有结构有内容的完整页面
  4. 把渲染完的页面返回给客户端

2. 客户端如何渲染

当服务器接收到请求后,把需要的页面代码返回给客户端,而第一次渲染完只有结构和样式没有数据,服务器获取到数据请求后,把数据找到,返回给客户端,然后客户端把获取的数据展示在页面中,这就是异步的 js 区域页面局部刷新。

3. 服务器渲染的的特点
  1. 我们看到的内容都是在服务器端渲染的(JSP / PHP / ASP / ASP.NET / NODE…)客户端只是把所有渲染好的内容呈现在页面中而已,然而我们第一次渲染完,页面中的某部分数据需要更新了,我们需要让服务器整体重新的渲染一次(包含最新的数据),把最新的页面返回给客户端,客户端只能整体刷新页面展示最新的内容 -> 全局刷新性能和体验等都非常的差,而且服务器压力也很大
  2. 如果服务器性能比较高,页面呈现出来的速度会快一些,因为只要从服务器拿到内容,一切信息都已经准备好了
  3. 由于内容在服务器端就已经渲染好了,所以页面渲染完成后,在页面的源代码中都可以看到内容,有利于 SEO 搜索引擎优化

4. 客户端渲染数据内容特点
  1. 可以实现页面中内容局部刷新,而且渲染的操作交给客户端来做 -> 体验好,减轻了服务器的压力
  2. 而且开始可以只把部分区域的数据获取到,滚动到某个区域后,再请求对应的数据也可以,实现数据的分批异步加载,提高性能体验
  3. 由于客户端渲染的内容没有出现在页面的源代码中, 不利于 SEO 优化。

二、当代项目开发的整个架构模型

  1. 纯服务器渲染(需要做 SEO 优化或者是技术氛围问题)-> 不推荐
  2. 混编模式:部分内容是服务器渲染,部分内容是客户端渲染 -> 常见的
  • 骨架屏:首屏内容都是服务器渲染的,目的是让页面一打开就能把首屏内容加载出来。其余屏都是 AJAX 逐一获取的,对于表单提交等数据交互操作也是客户端为主(局部刷新)
  1. 完全客户端和服务器端分离开发 -> 目前最常见的(推荐)
  • Vue / react / jQuery
  1. 把 Vue 和 react 在服务器端基于 node 来渲染 -> 服务器端渲染

三、什么是xml

XML:可扩展的标记语言,用自己定义的标签来储存数据的(在很早以前,我们基于 Ajax 和服务器我们基于 AJAX 和服务器进行交互的数据格式一般都已 XML 格式为主,因为它能清晰展示出对应的数据和结构层级;但是到后面,流行了一种新的数据格式 JSON,它不仅比 XML 更清晰展示数据的结构,而且同样的数据存储,JSON 更加轻量,也方便解析和相关的操作,所以现在前后端的数据交互都已 JSON 格式为主)

四、Ajax的基础操作

  1. 创建 Ajax 实例
let xhr = XMLHttpRequest;

但是 ie 低版本浏览器中用的是 new ActiveXObject() 高程3中 js 惰性编程思想,关于 xhr 的兼容处理

  1. 打开 url (配置发送请求的信息)
xhr.open('GET','/json/xxx.json','true')

第一个参数:HTTP 请求方式
第二个参数:URL 请求地址 (api 接口地址)
第三个参数:ASYNC:设置同步或者异步,默认true 是同步,false 是异步
第四个参数:USER-NAME:传递给服务器的用户名
第五个参数:USER-PASS:传递给服务器的密码

  1. 监听 Ajax 状态,在状态为/^\d&/的时候,获取服务器响应的内容
xhr.onredaystatechange = function () {
	if (xhr.readyState === 4 && /^(2|3)\d{2}&/.test(xhr.status)) {
		let result = xhr.responseText;
	}
}
  1. 发送请求
xhr.send(null);

send 中放的是请求主体内容

Ajax 任务发送请求到服务器,从服务器获取到相应的内容,从 send 后开始,到 xhr.readystate === 4 的时候算任务结束

ajax基础
        $.ajax({
            url:"",
            type:"post",
            data:{
                userName:a.value,
                passWord:b.value
            },
            success:function(data){
                // 当请求成功,会执行此函数
                //{}
                if(data.status===0){
                    // 请求成功
                }else if(data.status==1){
                    //该用户未注册
                }else if(data.status==2){
                    // 密码输入错误
                }

            }
        })
        
        // ajax   axios fetch  $.ajax({});
        // typeScript fluter
        // axios.get("data.json").then(function(data){

        // });

ajax的readstate
        // script的src  img的src   link   浏览器的url地址栏; ajax
        // XMLHttpRequest 是一个内置的类;
        //1. 创建了一个ajax的实例;
        let xhr = new XMLHttpRequest;
        console.log(xhr.readyState);
        //2.请求方式,请求路径,同步异步;
        xhr.open("get","11.html",false);
        console.log(xhr.readyState);
        //3.监听readystate发生改变的方法;
        xhr.onreadystatechange=function(){
            // 如果是同步,只输出4;如果是异步会输出2 3 4;
            // 如果是同步,如果请求不完,不会执行这个回调,但是readyState也会发生2-->3-->4的变化,
          只是不能执行而已;等上面执行完,那么readyState已经变成了4;所以只会输出结果4// readyState不同,说明请求进行到了不同的阶段;
            //console.log(xhr.readyState);
            if(xhr.readyState===4&&/^2\d{2}/.test(xhr.status)){
                // 说明数据已经传输到了客户端
            }
        }
        //4.发送请求
        xhr.send();
        // xhr.readyState : 0 1 2 3 4;代表了ajax不同的实例状态;
        // readyState :代表了该请求进行到了不同的阶段;
        // 0 : 创建ajax实例成功;
        // 1 : 确定好了请求的方式,请求的路径以及同步异步;
        // 2 : 服务器已经接受到了客户端的请求,并且把响应头传给了客户端;
        // 3 : 服务器正在向客户端发送数据
        // 4 :客户端全部接受到了数据,那么状态变成4;

ajax的状态码
        let xhr = new XMLHttpRequest;
        console.log(xhr.readyState);
        //2.请求方式,请求路径,同步异步;
        xhr.open("get","11.html",false);
        console.log(xhr.readyState);
        //3.监听readystate发生改变的方法;
        xhr.onreadystatechange=function(){
            if(xhr.readyState===4&&/^2\d{2}/.test(xhr.status)){
                
            }
        }
        //4.发送请求
        xhr.send();
        // 1.readyState

        // 2.status : 都是xhr这个实例上的一个属性名,当这个实例的请求操作进行到不同阶段时,
会不断更改readyState;当请求回来以后,这个请求就会更改这个实例的status,来表示该请求的结果;
        // 200 : 成功
        // 301 : 永久重定向 ;将域名重定向一个新的域名上;
        // 304 : 有缓存
        // 307:  临时转移
        // 400 : 报文存在语法错误
        // 401 : 请求需要验证
        // 403 :没有权限访问
        // 404 : 路径错误
        // 500 : 服务器的未知错误
        // 503: 超负荷;当用户的访问量超过服务器承受的最大用户量;负载均衡【node】

ajax的请求方式
   <script>
        let xhr = new XMLHttpRequest;
        console.log(xhr.readyState);
        //2.请求方式,请求路径,同步异步;
        xhr.open("post","11.复习.html",false);
        //3.监听readystate发生改变的方法;
        xhr.onreadystatechange=function(){
            if(xhr.readyState===4&&/^2\d{2}/.test(xhr.status)){ 
            }
        }
        //4.发送请求
        xhr.send({username:"aaa"});

        // 前端: 请求头请求体
        // 后端: 响应头响应体

        //重点
        // 1. get : 一般用于获取数据(获取订单、获取所有用户)
        //   1): get请求传参通过地址栏传参,把数据拼接到url问号的后面
        //   2): 各个浏览器对地址栏url大小由要求,不可以无限传参;IEurl控制4Kb
        //   3):  直接将数据暴露在地址栏上,安全性较低
        //   4): get请求会走缓存,如果不想走缓存,在url的后面拼接一个随机的时间戳;
        // 2. post :一般用于向服务器发送数据(登录,注册,提交订单...)
        //   1) : post传递数据是放到请求体中,传递给服务器
        //   2) :数据大小没有要求
        //   3) : 存放在请求体中,安全系数高
        //   4) : post请求不走缓存

        // delete : 删除操作
        // head 
        // put 


        $.ajax({
            url:"data.json",
            type:"get",// 如果不传参数,默认会走get请求
            data:{username:11,password:22},
            async:false,// 如果不写,默认是异步
            //cache:false,// 默认会走缓存,如果是false,是不走缓存的
            success:function(data){
                // data: JSON格式的对象;
            },
            error:function(){
                // 如果请求失败,会执行这个函数
            }
        })
    </script>

五、HTTP的请求方式

不论是 GET 和 POST 都可以吧信息传递给服务器,也能从服务器获取到结果,只不过是谁多谁少的问题
真实项目中用对应的请求方式,会使请求变得更加明确(语义化),不遵循这些方式也可以,最起码浏览器在语法上是允许的:但是这些是开发者们相互约定俗成的规范

本质区别:GET 系列传递给服务器信息的方式一般采用问号传参,而 POST 系列传递给服务器信息的方式一般采用设置请求主体

  1. GET 传递给服务器的内容比 POST 少,因为 URL 有最长大小限制(IE 浏览器一般限制 2kb ,谷歌浏览器一般限制为 4 ~ 8kb,超过长度的部分自动被浏览器截取了)
xhr.open('GET', '/list ? name = zhufeng & year = 10 & xxx = xxx...')
xhr.send('....')  // 请求主体中传递的内容理论上没有大小限制,但是真实项目中,为了保证传输的速度,我们
// 会自己限制一些
  1. GET 会产生缓存(缓存不是自己可控制的):因为请求的地址(尤其是问好传递的信息一样),浏览器有时候会认为你要和上次请求的数据一样,拿的是上一次信息,这种缓存我们不期望有,我们期望的缓存是自己可控制的;所以真实项目中,如果一个地址,GET 请求多次,我们要去除这个缓存
// 解决办法设置随机数
xhr.open('GET', '/list ? name = zhufeng &_ = '+Math.random());
...
xhr.open('GET', '/list ? name = zhufeng &_ = '+Math.random());
  1. GET 相比较 POST 来说不安全,GET 是基于问号传参传递给服务器内容,有一种技术叫做 URL 劫持,这样别人可以获取或者篡改传递的信息,而 POST 基于请求主体传递信息,不容易被劫持

GET系列请求:一般用于从服务器获取信息,给的少拿得多

  • GET
  • DELETE 一般应用于告诉服务器,从服务器上删除点东西
  • HEAD 只想要获取响应头内容,告诉服务器响应主体内容不要了
  • OPTIONS 试探性请求,发个请求给服务器,看看服务器能不能收到,能不能返回

    POST系列请求:一般用于给服务器推送信息,给的多拿得少
  • POST
  • PUT 和 DELETE 对应,一般是想让服务器把我传递的信息存储到服务器上(一般应用于文件和大型数据内容)

    客户端怎么把信息传递给服务器?
  • 问号传参:xhr.open(‘GET’,‘getdata ? xxx = xxx & xxx = xxx’)
  • 设置请求头 :xhr.setRequestHeader([key],[value])
  • 设置请求主体:xhr.send(请求主体信息)

服务器怎么把信息返回给客户端?

  • 通过响应头
  • 通过响应主体(大部分信息都是基于响应主体返回)

1. 请求时间

xhr.timeout = 10 设置 AJAX 的等待时间,超过这个事件算 AJAX 的延迟
xhr.ontimeout = function () {} 超过请求时间做的事
xhr.abort() 手动中断 AJAX 请求
xhr.withCredentials = true 在跨域请求中允许携带证书(携带 COOKIE)

2. AJAX状态码

xhr.redayState获取状态码

0: UNSEND 未发送,创建一个 xhr,初始状态是0
1: OPENED 已经打开,执行了 xhr.open
2: HEADERS_RECEIVED 响应头信息已经返回给客户端,发送请求后,服务器会依次返回响应头和响应主体的信息
3: LOADING 等待服务器返回响应内容
4: DONE 响应主体信息已经返回给客户端

六、 jQuery中AJAX的应用

$.ajax() 基于原生 js 的 ajax 四步进行封装

  1. $.ajax([URL],[OPTIONS])
  2. $.ajax([OPTIONS]) URL在配置项中(推荐)
  3. $.get/post/getJSON/getScript()

1. 配置项信息(jQuery中AJAX)

url:请求的 API 接口地址

method:HTTP 请求方式,默认 GET

data:传递给服务器的信息,默认 null(可以是字符串,可以是对象,而且如果 GET 系列请求,JQ 会自动把信息拼接到 URL 的末尾,基于问号传参传递给服务器;如果是 POST 请求,JQ 会基于请求主体,把信息传递给服务器)
dataType:预设服务器返回的结果格式(服务器返回的一般都是 JSON 格式的字符串,如果我们设置了 DATA-TYPE,JQ 会根据设置的类型,把服务器返回的结果处理为对应的格式),支持的内容text / json / xml / html / script / jsonp(跨域) =>不影响服务器返回的结果,只是把服务器返回的结果进行二次处理

async:是否为异步操作,默认是 TRUE,代表异步操作

cache:缓存处理,只对 GET 系列请求有作用,默认是 TRUE 不处理缓存,当我们设置 FALSE 后,JQ 帮我们在 URL的末尾设置一个随机数

contentType:设置传递给服务器内容的格式类型 默认是"application/x-www-form-urlencoded"
客户端传递给服务器信息的格式(类型一般都是字符串),常用的:
form-data 表单数据:JSON 格式 ‘{“name”:“xxx”,“lx”:1}’
x-www-form-urlencoded:name=xxx&lx=1
raw:纯文本格式

headers:设置请求头信息,他是一个对象
timeout:设置超时的时间
success:回调函数,当数据请求成功执行,方法中的参数就是从服务器获取的结果
error:回调函数,数据请求失败执行,方法中的参数是错误信息

    <script>
    // $ === jQuery
    // ajax都可以传递什么参数
    $.ajax({
        url:"data.txt",
        type:"get",
        async:false,// async : 同步异步,如果不写,默认是异步;
        cache:false,// 默认走缓存,true是走缓存,false是不走缓存;
        data:{},
        dataType:"json",// 请求来的数据格式
        success:function(data){
            // 当请求成功执行的回调函数;并且数据传递给这个回调函数的实参;
            // 默认是json格式的对象
        },
        error:function(){
            // 请求失败执行的回调函数
        },
        beforeSend:function(xhr){
            // 在发送请求之前,执行回调;一般用于设置请求头;
            // xhr: 就是ajax的实例
            xhr.setRequestHeader();
        },
        context:document.body,
        complete:function(){
            // 不管成功还是失败,都要调用这个方法;
        },
        timeout:1000,// 设置请求的超时时间;
        username:"",
        password:"",// 请求认证的用户名和密码
        xhr:function(){

        }
    })
    </script>

2. AJAX同步异步
    <script>
        let  xhr  = new XMLHttpRequest;
        xhr.open("get","1.复习.html",false);// true :异步 false 同步;
        xhr.onreadystatechange=function(){
            console.log(xhr.readyState);
        }
        xhr.send();// 发送请求
        console.log(100);

        同步: 4 100;
        异步:100 2  3  4;
        同步异步的应用场景
        1. 异步:
        打开首页有十几个请求;如果该请求跟其他请求的数据没有关系,那么一般用异步;
        2. 同步: 如果一个请求回来的数据会作为下一个请求的参数,这时第一个请求完成以后再发第二个请求,
        那么第一个请求应该用同步;

        JS本身是一个单线程;但是浏览器是多线程;浏览器可以同时发送处理多个请求;
        能用异步就别用同步;
        $.ajax({
            url:"data.txt",
            async:true,
            success:function(data){
                $.ajax({
                    url:"data.txt",
                    data:a.a,
                    success:function(data){
                        $.ajax({

                        })
                    }   
                })
            }
        })
        $.ajax();// 1s
        $.ajax();// 2s
        $.ajax();// 3s
        // 最终就需要3秒;  
        // promise       
    </script>

3.封装jequry中的AJAX的应用
        function ajax(options){
            // 准备一个默认的对象
            let default_op={
                type:"get",
                async:true,
                cache:true,
                success:null,
                data:null
            }
            // 循环options,给default中属性名重新赋值;
            for(let key in options){
                default_op[key]=options[key];
            }
            if(default_op.type.toLowerCase()==="get"){
                // 为了解决传参;get请求需要将data的值拼到url的后面;
                let str=`?`;
                for(let key in default_op.data){
                    str+=`${key}=${default_op.data[key]}&`
                }
                str=str.slice(0,str.length-1);
                default_op.url+=str;
                if(!default_op.cache){
                    // 如果不走缓存,在后面添加时间戳;
                    default_op.url+= `&time=${Date.now()}`;
                }
            }
            let xhr = new XMLHttpRequest;
            // 取到default_op中的值;给open方法传入参数;
            xhr.open(default_op.type,default_op.url,default_op.async);
            xhr.onreadystatechange=function(){
                if(xhr.readyState===4&&/^2\d{2}/.test(xhr.status)){
                    // 把请求回来的数据转成JSON格式的对象,传给success的回调;
                    let val = JSON.parse(xhr.responseText);
                    default_op.success(val);
                }else if(xhr.readyState===4){
                    // 如果请求不成功,执行失败的回调;
                    default_op.error();
                }
            }
            // 发送请求;
            if(default_op.type==="get"){
                default_op.data=null;
            }
            xhr.send(default_op.data);
        }
        ajax({
            url:"data.txt",
            type:"get",
            data:{username:"a",password:"b"},
            cache:false,
            success:function(data){
                console.log(data);
            }
        })

七、ajax

ajax设置请求头
    <script>
        // 有些请求需要通过请求头传递给后端一些数据或指责一些请求信息;请求头比请求体要早到达服务器,
      服务器可以根据请求头的信息,进行相应的处理;
        // 一般情况下,会将请求的cookie放在请求头中,传递给服务器;
        let  xhr  = new XMLHttpRequest;
        xhr.open("get","1.html",false);
        xhr.onreadystatechange=function(){
            console.log(xhr.readyState);
        }
        // 当真正的工作中,cookie是后端生成的;
        xhr.setRequestHeader("Cookie","headertest");
        // 在发送请求之前设置这些请求头的信息
        xhr.send();   
    </script>

promise的ajax
         promise : 解决异步回调地狱的一种方案;
        第二个请求需要等到第一个请求成功以后才能执行,这种无限嵌套的请求就是回调地狱;
        将异步的回调同步的展示出来;
        $.ajax({
            url:"/login",
            type:"post",
            success:function(data){
                // data:{statusCode:0}// 这是后端返回的数据
                if(data.statusCode===0){
                    $.ajax({
                        url:"/order",
                        type:"get",
                        success:function(){
                        }
                    });
                }
            }
        });
       
        if(pathname==="/login/list"){
            // 登录
        }
        if(pathname==="/order"){
            // 请求订单
        }

        let getJSON=function(str){
            // promise  和  ajax实例
            let promise = new Promise(function(resolve,reject){
                let xhr = new XMLHttpRequest();
                xhr.open("get",str,false);
                xhr.onreadystatechange=function(){
                    if(xhr.readyState===4&&/^2\d{2}/.test(xhr.status)){
                        let val = JSON.parse(xhr.responseText);
                        resolve(val)
                    }else if(xhr.readyState===4){
                        reject()
                    }
                }
                xhr.send();
            })
            return promise;
            // 返回一个promise的实例;
        }
        getJSON("data.txt").then(function(data){
            console.log(data); 
        })
        getJSON("/userList").then(function(data){
            // 把promise请求回来的数据,传递给then的回调函数中的参数
            return getJSON("/order")
        }).then(function(data){
            return getJSON("/list")
        }).then(function(data){

        }).catch(function(){
            // 如果有任意一个请求失败,触发catch对应的回调;
        })
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值