异步编程

同步与异步

同步:阻塞式,一定要等上一段代码出来之后,才能继续执行

异步:非阻塞式,什么时候执行完了,会通过事件触发来告诉我们(事件是其中一种方式)

FileReader(文件读取器)、setTimeout、setInterval

ajax

(异步JavaScript 和 XML【可扩展标记语言】)

  • url:访问的地址
  • method:请求方式 如:GET、POST
  • data:传递给后端的数据(POST才用)
  • callback:回调函数 ()

function ajax(url,method,data,callback){

​ // 创建XMLHttpRequest对象:xml

​ let xhr = new XMLHttpRequest()

​ // 打开通道

​ xhr.open(method,url)

​ // 发送请求

​ xhr.send(data)

​ // 通过事件来获取响应结果

​ xhr.onreadystatechange=function(){

​ // readstate=4说明请求已经完成

​ if(this.readstate == 4){

​ if(status == 200){

​ callback(JSON.parse(this.responseText))

​ }else{

​ console.log(this.statusText)

​ }

​ }

​ }

}

ajax(url.‘GET’,null,function(result){

​ resout.forEach(item => {

​ let

​ })

})

    /**
     * url 访问地址
     * method 请求方式:GET、POST
     * data 传递给后端的数据(POST才用)
     * callback 回调函数(将异步的结果放进去)
     */
    function ajax(url,method,data,callback){
        //1.创建XMLHttpRequest对象:xhr
        let xhr = new XMLHttpRequest();
        //2.打开通道
        xhr.open(method,url);
        if(method.toUpperCase()=='POST'){
            xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
        }
        //3.发送请求
        xhr.send(data);
        //4.通过事件来获取响应结果
        xhr.onreadystatechange=function(){
            //5.readyState=4说明整个请求已经完成了
            if(this.readyState==4){
                //6.获取HTTP状态码,如果是200则成功
                if(this.status==200){
                    let res = JSON.parse(this.response)
                    if(res.errcode){
                        alert(res.errmsg)
                        return;
                    }
                    //将结果传给回调函数
                    callback(res);
                }else{
                    //7.如果状态码不是200,我们就打印状态文本,例如:404 文本就是 Not Found
                    console.log(this.statusText)
                }
            }
        }
    }

在onreadystatechange事件中,通过ajax的readyState 监听服务器的处理进度:
0:初始化,XMLHttpRequest对象还没有完成初始化
1:载入, XMLHttpRequest对象开始发送请求 —open
2:载入完成,XMLHttpRequest对象的请求发送完成—send
3:解析,XMLHttpRequest对象开始读取服务器的响应
4:完成,XMLHttpRequest对象读取服务器响应结束

Content-Type:

  1. 纯文本 text/plain
  2. JSON application/json
  3. form表单 application/x-www-form-urlencoded
  4. 文件上传 multiple-form

回调地狱

多层回调函数嵌套,使得程序变得难以维护,可读性差

 setTimeout(function() {
        console.log('Yay!');
        setTimeout(function() {
            console.log('Yahoo!');
                setTimeout(function(){
                //回调地狱
            },1000)
        }, 1000)
    }, 1000);

Promise(承诺)

ES6推出了Promise语法结构来解决回调地狱问题。
这也就表达了将来会执行的操作,代表异步操作。

三种状态:
pending(进行中)、fulfilled(已成功)和rejected(已失败)

状态改变的过程:
pending->fulfilled
pending->rejected
一旦变成了成功或失败状态,状态就不会再变化。

创建Promise实例:

    const promise = new Promise((resolve, reject) => {
        // do something here ...
        if (success) {
            resolve(value); // fulfilled
        } else {
            reject(error); // rejected
        }
    });
    //通过then方法,分别指定resolved状态和rejected状态的回调函数
    promise.then(function(value) {
        // success
    }, function(error) {
        // failure
    });

用Promise改造Ajax:

    /**
     * url 访问地址
     * method 请求方式:GET、POST
     * data 传递给后端的数据(POST才用)
     */
    function ajax(url,method,data){
        return new Promise((resolve,reject)=>{
            //1.创建XMLHttpRequest对象:xhr
            let xhr = new XMLHttpRequest();
            //2.打开通道
            xhr.open(method,url);
            if(method.toUpperCase()=='POST'){
                xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
            }
            //3.发送请求
            xhr.send(data);
            //4.通过事件来获取响应结果
            xhr.onreadystatechange=function(){
                //5.readyState=4说明整个请求已经完成了
                if(this.readyState==4){
                    //6.获取HTTP状态码,如果是200则成功
                    if(this.status==200){
                        let res = JSON.parse(this.response)
                        if(res.errcode){
                            alert(res.errmsg)
                            return;
                        }
                        //将结果传给回调函数
                        resolve(res);
                    }else{
                        //7.如果状态码不是200,我们就打印状态文本,例如:404 文本就是 Not Found
                        reject(this.statusText)
                    }
                }
            }
        })
    }
    let url = 'http://yapi.smart-xwork.cn/mock/91220/user/list'
    ajax(url,"GET",null).then(result=>{
        if(result instanceof Array){
            //遍历结果
            result.forEach(item=>{
                //创建LI标签
                let li = document.createElement("li");
                li.innerHTML = item.name +":"+ item.sex;
                //将LI追加到UL中
                document.getElementById("parent").appendChild(li);
            })
        }
    },error=>{
        console.log("失败:" +error);
    })

Promise中的异常捕获:

方式一:
ajax(‘GET’,’api/seller.do’,’username=jackie’).then((data)=>{
console.log(data);//成功获得结果
},(err)=>{
console.log(err);//获取错误信息
}

方式二:
ajax(‘GET’,’api/seller.do’,’username=jackie’).then((data)=>{
console.log(data);//成功获得结果
}).catch(err=>{
console.log(err);//获取错误信息
})

Promise.all

    <script>
      function p1() {
        return new Promise((resolve, reject) => {
          resolve("sccess");
        });
      }
      function p2() {
        return new Promise((resolve, reject) => {
          reject("over");
          // resolve("sccess");
        });
      }
      function p3() {
        return new Promise((resolve, reject) => {
          resolve("sccess");
        });
      }

      Promise.all([p1(), p2(), p3()]).then(
        (res) => {
          console.log(res);
        },
        (err) => {
          console.log(err);
        }
      );

      Promise.all([p1(), p2(), p3()])
        .then((res) => {
          console.log(res);
        })
        .catch((err) => {
          console.log(err);
        });
    </script>

Promise.allSettled

同时启动多个,不论成功还是失败都会返回全部的结果。

  • Promise.allSettled([p1(),p2(),p3()])
    <script>
      function p1() {
        return new Promise((resolve, reject) => {
          resolve("sccess");
        });
      }
      function p2() {
        return new Promise((resolve, reject) => {
          reject("over");
          // resolve("sccess");
        });
      }
      function p3() {
        return new Promise((resolve, reject) => {
          resolve("sccess");
        });
      }
      Promise.allSettled([p1(), p2(), p3()]).then((arr) => {
        console.log(arr);
      });
    </script>

(3) [{…}, {…}, {…}]
    0: {status: 'fulfilled', value: 'sccess'}
    1: {status: 'rejected', reason: 'over'}
    2: {status: 'fulfilled', value: 'sccess'}
    length: 3
        [[Prototype]]: Array(0)

Promise.race()

race:比赛

多个promise比赛,看谁先执行到最终状态。率先改变

  • promise.race[p1,p2,p3].then(res=>{console.log(res)})
<script>    
     Promise.race([p1(), p2(), p3()])
        .then((arr) => {
          console.log(arr);
        })
        .catch((arr) => {
          console.log(arr);
        });
    </script>

async

  • 给函数前加async关键字,函数的返回值就会变成一个Promise对象
  • 如果我们手动在函数里面return了一个值,则这个值就是Promise对象里面的value,通过then可以取出
    <script>
      async function play() {
        return 123;
      }
      console.log(play()); // promise
      play().then((arr) => console.log(arr));
    </script>

async - await

  • async_await:能让异步代码看起来像是同步代码
  <script>
    async function show(){
      return 123;
    }
    async function play(){
      var res = await show()
      console.log(res);
    }
    play()
  </script>
  <body>
    <script>
      function ajax(url, method, data) {
        return new Promise((resolve, reject) => {
          let xhr = new XMLHttpRequest();
          xhr.open(method,url);
          xhr.send(data);
          xhr.onreadystatechange = function () {
            if (this.readyState == 4) {
              if (this.status == 200) {
                let res = JSON.parse(this.response);
                resolve(res);
              } else {
                reject(this.statusText);
              }
            }
          };
        });
      }

      async function play() {
        try {
          let url =
            "http://yapi.smart-xwork.cn/mock/94700/user/information/user/get";
          let res = await ajax(url, "GET", null);
          console.log(res);
        } catch (error) {
          console.log(error);
        }
      }
      play();
    </script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值