AXAJ与JavaScript中的异步编程元素

  目前,JavaScript的编程元素相比一些主流的编程语言比如C#和Java还是不算多,但是应用它的语法糖很多,如果不熟悉这些语法糖,很多的代码将难以阅读与理解,就比如同样是链式编程,在代码组织上,C#上就比JavaScript来得简明,也可能是个人习惯,觉得JavaScript以后容纳更多的编程元素后将更难以阅读,但它的发展还远没有到头,按现在的发展趋势,今后它有可能成为一流的、应对所有应用的最佳开发工具。

  对于异步编程,就是通常我们俗称的AXAJ即Asynchronous Javascript And XML(异步JavaScript和XML),我们都认为它一种具体的编程技术,实质上,我们应该理解AXAJ为一系列的支持异步编程的方法、工具的集合(也可以说是一种思想),这个集合里面有很多的对象和方法来帮助我们用JavaScript语言实现异步编程,比如XMLHTTPRequest、JQuery里面的AXAJ、Promise、Fetch、Axios、async/await等等,Javascript语言本身是不支持异步编程的,但JavaScript的宿主浏览器支持,所以Javascript通过回调函数将需要异步处理的调用放到浏览器的事件循环队列,这样就实现了异步编程。

  我们怎样使用JavaScript来实现异步编程的呢?

  1、网页嵌套、定时器

  1998年,我使用HTML + CGI开发一个Web应用,使用Web页面框架来实现局部刷新,程序提交数据时候将调用页面底部的响应而提交按钮所在的页面,这样只是底部显示变化数据【其他页面如有数据变化,这个页面的处理程序也一样可以处理】而整个页面不动。

  使用定时器来实现异步编程在以前也用到过,类似在一个消息队列中不断加入消息检测,满足条件了就执行处理函数。

  这些都太老旧了。

  2、XMLHTTPRequest

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>XMLHttpRequest</title>
</head>
<body>
    <script>
        //1、创建Ajax对象
        let xhr=new XMLHttpRequest();
        //2、设置请求信息
        //xhr=open(请求方式,请求地址,是否异步)
        xhr.open('Post','http://127.0.0.1/ES6_Base/ASD.php',true);
        //3、配置请求完成事件
        xhr.setRequestHeader('content-type','application/x-www-form-urlencoded')
        xhr.onreadystatechange=function(){
            if(xhr.readyState===4){
                if(xhr.status>=200 && xhr.status<300){
                        let res=JSON.parse( xhr.responseText );
                        console.log( "用户名:"+res.Name );
                        console.log( "密码:"+res.Password );
                }else{
                         console.log(xhr.status);
                }
            }
        }
        //4、发送请求
        xhr.send("Name=ASD&Password=123");
    </script>
</body>
</html>

  PHP脚本:

<?php
    $returnArr=[];//准备返回的数组
    $Name = $_POST['Name'];
    $Password = $_POST['Password'];

    $returnArr['Name']=$Name;
    $returnArr['Password']=$Password;

    header('Content-type:text/json');
    echo json_encode($returnArr,JSON_UNESCAPED_UNICODE);  
?>

  返回结果:

用户名:ASD
密码:123

  最开始的时候,大家都习惯使用这样的编码来实现异步编程,但这样原生的编码方式不方便,如果有嵌套那么代码也显得冗长,不方便阅读,现在几乎没有人再使用它。

  Jquery的出现让编程方式做了很大的改变。

  3、JQuery的AXAJ方法(函数)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="jquery-3.4.1.min.js" charset="utf-8"></script>
    <title>Jquery</title>
</head>
<body>
    <script>
        $.ajax({
                url:'http://127.0.0.1/ES6_Base/ASD.php',
                data:{
                        "Name":"ASD",
                        "Password":"123"
                        },
                type:'POST',
                async:true,
                success:function (JsonData) {
                    console.log("用户名:"+JsonData['Name']);						
                    console.log("密码:"+JsonData['Password']);						
                }
        });							 
    </script>
</body>
</html>

  返回和上面一样的结果。

  JQuery也是封装了原生AXAJ的API,使用起来方便快捷。

  在很多框架里可以看到JQuery的身影,它们都集成了JQuery,比如LayUI、EasyUI等。

  JQuery自2006年诞生起在很长一段时间里相当流行,是当时使用最为广泛和频繁的函数库,但目前逐渐在淡出。主要原因可能是回调地狱、ECMAScript6下有更好的异步编程模式等等。

  4、Promise对象

  Promise是ECMAScript6中提供的用于解决异步编程的类。

  使用它有助于书写优雅、复杂的异步任务,改善了异步编程的困难,避免了回调地狱,比传统的解决方案回调函数和事件更合理和更强大。

  通俗地理解,就是使用同步编程的写法可以解决异步编程的问题。

        const p=new Promise( (resolve,reject)=> {
            //执行任务
            //任务成功时执行resolve,可以包含结果
            //任务失败时执行reject,可以包含错误提示信息
        }).then( ( value )=>{
            //获取resolve的结果再进一步进行处理
        }).catch( ( reason )=>{
            //获取reject的信息并进一步处理
        })

  上面是我们经常使用的写法,也可以使用下面的写法,效果与上面一样。

        const p=new Promise( (resolve,reject)=> {
            //执行任务
            //任务成功时执行resolve,可以包含结果
            //任务失败时执行reject,可以包含错误提示信息
        }).then( ( value )=>{
            //获取resolve的结果再进一步进行处理
        } ,( reason )=>{
            //获取reject的信息并进一步处理
        })

  注意点:

  (1) promise对象有三种状态,分别是pending(准备中)、fulfilled(成功/完成)、rejected(拒绝/失败)。

  (2) promise对象的状态改变是一次性的,也就是只能改变一次,要么pending -> fulfilled,要么pending -> rejected。

  (3) 通过执行resolve改变promise对象状态由pending -> fulfilled,执行reject改变promise对象状态由pending -> rejected。

  (4) then方法返回的是promise对象,promise支持方法调用的链式写法。

  (5) 当promise的状态为rejected或者执行体中的代码异常时执行catch函数。

  虽然promise相比Jquery的Axaj有很大的改观,的确也解决了异步编程中常遇到的回调地狱、回调函数的嵌套问题,但实际写代码过程中,依然觉得promise如果then很多的情况下阅读代码不是很方便。

  promise在现在的异步编程中应用相当普遍。

  5、asyc/await

  比较而言,ECMAScript7(2016年)中应用于异步编程的asyc/await则人性化了许多,真正实现了异步处理同步化(写法)。

        async GetListTask(id){
            let result;
            result=await this.GetListTask1(id)    //等待获取任务列表1
            //......处理            
            result=await this.GetListTask2(id)    //等待获取任务列表2
            //......处理            
        }

  注意点:

  (1) 如果函数中包含了await但函数前面没有冠以async则程序会报错。

  (2) 函数前面直接使用asyc但函数体内无await程序并不会报错,但无意义,asyc/await必须成对出现才有意义。

  现在很多设计异步编程的的开发都使用asyc/await

  6、Generator(生成器)

  通过生成器返回的迭代器对象,根据需要执行next()方法来控制程序进度。

        function* ToDo() {
            console.log("执行第一步任务");
            yield 111;

            console.log("执行第二步任务");
            yield 222;

            console.log("执行第三步任务");
        }

        const myToDo = ToDo(); //获取生成器对象
        console.log(myToDo.next().value); // 输出:111,到yield 111为止
        
        console.log(myToDo.next().value); // 输出:222,到yield 222为止
        
        console.log(myToDo.next().value); // 输出:undefined,任务执行完毕

输出结果:
执行第一步任务
111
执行第二步任务
222
执行第三步任务
undefined

  通过迭代来控制:

        for(let item of myToDo) {
            console.log( item ) 
        }

结果输出:
执行第一步任务
111
执行第二步任务
222
执行第三步任务

  这种方式有特定的应用场景,感觉还是习惯asyc/await

  7、Axios

  Axios是一个基于Promise、用于浏览器和Node.js的HTTP客户端,它也是对原生XMLHTTPRequest对象的promise封装。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Axios</title>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
    <script>
        axios.post('http://127.0.0.1:8018/JS/ECMAScript6/ES6_Base/ASD.php',"Name=ASD&Password=123")
        .then(function(response){
            console.log('得到结果')
            console.log(response.data);
        })
        .catch(function(error){
            console.log('错误提示')
            console.log(error);
        })
    </script>
</body>
</html>

  结果输出:

得到结果
{Name: "ASD", Password: "123"}

  前端框架中使用Vue的多使用axios来执行异步请求任务。

  8、fetch对象

  fetch被称为下一代的Ajax技术,采用promise方式来处理数据,代码结构比较简洁,fetch不是对XMLHTTPRequest对象的进一步的封装,是新的异步编程实现方法和规范。

  fetch默认不会带有cookie,需要添加配置项,fetch不能再请求过程中检测进度。

        fetch('http://127.0.0.1:8018/JS/ECMAScript6/ES6_Base/ASD.php',{method:'post',body:'Name=ASD&Password=123',headers:{ 'Content-Type':'application/x-www-form-urlencoded' }  }).then(data=>{
           //text()是fetch的一部分,它返回的是promise对象,用于获取后台返回的数据
            return data.text();
        }).then(result=>{
            //这里获得最终的数据
            console.log(result);
        })

结果输出:
{"Name":"ASD","Password":"123"}

  

猜你喜欢

转载自blog.csdn.net/dawn0718/article/details/127154092
今日推荐