关于JavaScript-3:AJAX与进阶

AJAX

1.什么是AJAX?

AJAX是浏览器提供的一套 API,可以通过 JavaScript 调用,实现局部/异步请求.

2.为什么要引入AJAX?

在没有AJAX之前,获取服务端数据需要网页刷新跳转,有了AJAX不需要网页跳转就可以发送请求.

需要网页刷新跳转的如:
1. link标签的href属性
2. script标签的src属性
3. img标签的src属性
4. a标签的href发送请求
5. 表单提交发送请求(Submit按钮)
6. iframe的src属性发送请求

3.原生AJAX

原生AJAX五部曲 代码
1.创建请求对象 var xhr = new XMLHttpRequest();
2.设置请求行(open方法) xhr.open(请求方式,请求路径,是否异步)
3.设置请求头(get请求不需要,post才需要) xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded');
4.发送请求&设置请求体(get通过url提交数据不需要,post才需要请求体) xhr.send(),格式:key=value,多个值用&连接
5.监听响应完成 xhr.onload(IE8不支持); xhr.onreadystatechange(所有浏览器都支持)

示例代码:

 //用ajax发一个局部请求步骤

        //1.创建请求对象
        //本质上 XMLHttpRequest 就是 JavaScript 在 Web 平台中发送 HTTP 请求的手段,所以我们发送出去的请求任然是 HTTP 请求,同样符合 HTTP 约定的格式
        var xhr = new XMLHttpRequest();

        //2.调用open方法设置请求行
        //参数1:请求方式
        //参数2:请求路径
        //相当于是设置请求行
        xhr.open('get','http://wthrcdn.etouch.cn/weather_mini?city=深圳');

        //3.设置请求头,(post请求才需要,get请求不需要)
        //xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded');

        //4.发送请求&设置请求体(post才需要,get通过url提交数据不需要)
        xhr.send();

        //5.监听响应完成事件(当响应完成会调用这个事件)
        xhr.onreadystatechange = function(){

            // 为什么要写这个判断条件?
            // #这个事件会调用3次,只有当请求状态为4才代表响应完成(这时才会有响应体),也就是xhr.readyState==4
            // ##上面只能保证响应完成,不能保证拿到正确的响应体,还要服务器正常响应,所以加一个 xhr.status == 200

            if(xhr.readyState == 4 && xhr.status == 200){

                //在判断里面处理响应体(所有代码都写在这里面)
                console.log(xhr.responseText);

            }

        }

4.jQuery中的AJAX

属性设置/请求方法 $.ajax $.get $.post
1.type:请求方式 需要设置 不用设置 不用设置
2.url:请求路径
3.data:提交的数据 字符串或对象 在jQuery1.12以前,是不支持传入对象,需要一个一个写参数 同$.get
4.dataType:表明响应体类型
5.success:响应成功的回调函数
6.error:响应失败的回调函数

$.ajax示例代码:

//jQuery在线CDN引用地址
<script src="https://cdn.bootcss.com/jquery/3.1.1/jquery.min.js"></script>
<script>
 $.ajax({
            // 请求方式
            type: "get",
            
            // 请求路径
            url: "http://wthrcdn.etouch.cn/weather_mini?city=深圳",

            // 请求提交的数据,get不需要
            // 传递的数据可以是字符串也可以是对象,传对象,它会自动把对象转换成字符串的形式
            // 1.data:"name=jack&age=16"
            // 2.data: { name: "jack", age: 16 }

             // 告诉jQuery,响应体是json类型的数据,帮我们自动转成对象,在控制台可以看到打印的是对象
             dataType: "json",

            // 响应成功的回调函数,obj就是响应体
            success: function (obj) {

                console.log('success');

                console.log(obj);

            },

            // 当发生错误,有可能是请求失败,也有可能是其他错误,会进到这个函数里
            error: function (res) {

                console.log('error');

                console.log(res);

            }
        });
</script>

5.进阶:基于Promise封装Ajax

(1)Promise 对象:ECMAscript 6 新增,主要用于解决异步回调的问题.

1.简单说是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果.
2.从语法上说,promise是一个对象,从它可以获取异步操作的消息.

(2)Promise对象的特点

1.promise对象代表一个异步操作,有三种状态,pending(进行中)、fulfilled(已成功)、rejected(已失败).
2.状态改变只有两种:从pending变为fulfilled,从pending变为rejected.
3.只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态,这也是promise:“承若”这个名字的由来.
4.一旦状态改变就不会再变,任何时候都可以得到这个结果,这与事件(event)完全不同,事件的特点是:如果你错过了它,再去监听是得不到结果的.

(3)Promise对象的创建:

//1.使用 new 调用 Promise 构造函数进行实例化.
//2.Promise 构造函数包含一个参数和一个带有 resolve(解析)和 reject(拒绝)两个参数的回调.
var promise = new Promise(function(resolve, reject) {

// 异步处理

// 当异步代码执行成功时,我们会调用resolve(...), 当异步代码失败时就会调用reject(...)

});

(4)Promise封装Ajax:

let hxios = {
    get(url) {
      // 返回新建的promise对象
      return new Promise((resolve, reject) => {
        // 1.设置请求对象
        let xhr = new XMLHttpRequest();
        // 2.设置请求行
        xhr.open('GET', url);
        // 3.设置请求头(get请求不需要)
        // xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        // 4.发送请求&设置请求体
        xhr.send();
        // 5.监听响应完成
        // 成功回调函数
        xhr.onload = function () {
          // promise resolve
          resolve(xhr.responseText);
        }

        // 错误回调函数
        xhr.onerror = function () {
          // 调用reject
          reject('请求出错啦')
        }
      
      })

    },
    post(url) {
      // 返回新建的promise对象
      return new Promise((resolve, reject) => {
        // 1.设置请求对象
        let xhr = new XMLHttpRequest();
        // 2.设置请求行
        xhr.open('POST', url);
        // 3.设置请求头
        xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        // 4.发送请求&设置请求体
        xhr.send();
        // 5.监听响应完成
        // 成功回调函数
        xhr.onload = function () {
          // promise resolve
          resolve(xhr.responseText);
        }

        // 错误回调函数
        xhr.onerror = function () {
          // 调用reject
          reject('请求出错啦')
        }
      })

    },

  }
Promise构造函数 promise实例对象
原型对象Promise.prototype上有then和catch方法 promise实例都可以调用then和catch方法

调用上述Promise封装的AJAX进行天气查询:

//promise.then(onCompleted, onRejected);方法实现链式调用.
//1.onCompleted:必需,成功时执行的回调函数.
//2.onRejected:可选,失败时执行的回调函数.
//3.promise.catch方法可以当作.then(null, rejection)的别名,失败时执行的回调函数.
//4.不管是then方法还是catch方法返回的都是一个新的Promise实例,这意味着Promise可以链式调用then和catch,每一个方法的返回值作为调用下一个方法的实例对象.
  hxios.get('http://wthrcdn.etouch.cn/weather_mini?city=深圳')
    .then(res => {
      console.log(res);
      // 查完了深圳查北京,返回promise对象
      return hxios.get('http://wthrcdn.etouch.cn/weather_mini?city=北京')
    }).then(res => {
      console.log(res);
      // 查完了北京查武汉,再次返回promise对象
      return hxios.get('http://wthrcdn.etouch.cn/weather_mini?city=武汉')
    }).then(res => {
      console.log(res);
    })

6.进阶:async/await协同promise发AJAX请求

(1)async/await:ES7(ES2017)中提出的前端异步特性:

async 关键词await(只能在async函数中使用)
用于声明一个函数是异步的 await可以让JS进行等待,直到这个异步执行得到结果后(返回的不是promise对象,await也会强制转换),JS才会继续往下执行

注意:有async的内层可以没有await,有await的外层一定要有async声明这是异步函数

调用上述Promise封装的AJAX+async/await进行天气查询:

// 用async 修饰的函数 内部的代码执行 是从上往下
  async function searchWeather() {
    // 希望按照顺序执行的代码 全都丢到 async修饰的函数中
    // await 把 后面 Promise 中then的 回调函数的参数 返回给你
    let res1 = await hxios.get('http://wthrcdn.etouch.cn/weather_mini?city=深圳')
    console.log(res1);
    let res2 = await hxios.get('http://wthrcdn.etouch.cn/weather_mini?city=广州')
    console.log(res2);
  }
  searchWeather();

本文同步发表在我的个人博客:https://www.lubaojun.com/

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容