当前位置:   article > 正文

ES6异步发送AJAX_es6 ruturn ajax

es6 ruturn ajax

ES6异步发送AJAX

异步与同步的区别

  • 同步:在上一个操作没有执行完前,下一个操作必须排队等待
  • 异步:CPU先把当前操作耽搁不执行,等主线任务执行完后再执行

ES6前的异步操作

  • 在ES6发布之前,要操作异步,只能使用递归或者回调函数来操作,但是这样会使得代码可读性差,难维护。
  • js的运行机制是单线程的,它首先会执行同步的操作,再按照代码的位置先后顺序执行异步操作。
  • js 中的核心异步执行函数是定时器和ajax
       setTimeout(console.log, 0, 1);
        console.log(2);
        // 2
        // 1
  • 1
  • 2
  • 3
  • 4

分析

这里,定义了一个setTimeout(),0ms后执行console.log(1),他的等待时间是0,并且它在console.log(2)前面。正常理解应该是先输出1,再输出2,但是并不是。这是因为setTimeout是异步执行函数,console.log是同步执行函数,在运行到setTimeout时,js引擎会把他先放进一个任务队列中,先不执行,接着运行console.log(2),直接输出控制台,同步函数执行完后再执行任务队列中的console.log(1)

任务: 实现一个获取新闻内容与评论的功能

分析

  • 分为两步:
    1. 根据newsId请求相应的新闻内容以及该新闻对应的评论的资源地址
    2. 根据上一次请求返回的评论URL地址,再次发送请求,获取对象的新闻

普通方法

    // ajax请求
    // 1. 根据newsId获取新闻
    
    function getNews(path, getComment){
        $.get(path, (data) => {
            data = JSON.parse(data); // 将json对象装换成js对象
            displayNews(data); // 展示新闻内容
            getComment(data.commentUrl); // 获取新闻评论
        })
    }


    function getComment(url){
        $.get(url, (data) => {
            data = JSON.parse(data); // 返回json数组,转出成js数组
            displayComment(data);// 展示新闻评论
        })
    }

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

返回数据

{commentUrl: “/Servlet/NewsCommentsServlet?newsId=1&page=1”, content: “这是条劲爆新闻!”, title: “中国万岁!”}
commentUrl: “/Servlet/NewsCommentsServlet?newsId=1&page=1”
content: “这是条劲爆新闻!”
title: “中国万岁!”

[{content: “评论1”}, {content: “评论2”}, {content: “评论3”}, {content: “评论4”}, {content: “评论5”}]
0: {content: “评论1”}
1: {content: “评论2”}
2: {content: “评论3”}
3: {content: “评论4”}
4: {content: “评论5”}

分析

我们会发现上面这样使用把获取评论的方法作为回调函数传入,会使业务逻辑的代码实现很分散,如果getComment后面还要发送其他请求,就有需要再传入一个回调函,请求多了就会产生一层层的回调函数,逻辑不清晰,出了bug,很难找,我们称这为回调地狱

为了解决上面回调地狱,代码逻辑分散,难维护等问题,ES6提出以下解决方案。


一、Generator

generator语法请看我的另外一篇文章
https://blog.csdn.net/weixin_46215920/article/details/113869165

  • 使用generator,可以把获取新闻内容和评论写在两个yield里,这样代码就变成了线性排列,逻辑清晰。
  • 如果有一个yield发生了错误,函数会提前结束,后面的代码都不会执行,比如请求新闻内容发生了错误,则不会发送请求评论。
    // 利用generator, 把获取新闻内容评论的业务都整合在了一个函数函数
    function* newsGenerator(path){
        let commentUrl = yield getNews(path); // 获取新闻内容
        yield getComment(commentUrl); // 获取评论
    }
   
    const news = newsGenerator('./Servlet/NewsServlet?newsId=1');
    news.next();// 第一调用next(), 获取新闻内容

    function getNews(path){
        $.get(path, (data) => {
            data = JSON.parse(data);
            displayNews(data);  // 展示新闻内容
            news.next(data.commentUrl); // 第二次调用next(), 获取评论  
        })
    }
    function getComment(path){
          $.get(path, (data) => {
            data = JSON.parse(data);
            displayComment(data);  // 展示评论
        })
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

二、Promise对象 – 期约

Promise语法请看我另一篇文章https://blog.csdn.net/weixin_46215920/article/details/113872957

  • 使用Promise的连锁(链式调用)
  • getNews()函数是用来发送ajax请求的,返回一个Promise对象
  • then里定义的resolve回调函数需要渲染返回数据以及请求调用getNews()再次发送并返回Promise对象
    
function getNews(url){
    // 利用了闭包
    let promise = new Promise((resolve,reject)=>{//执行一个异步操作
        $.get(url, (data) => {
            resolve(JSON.parse(data));
        })
    })
    return promise; //返回一个promise对象,其实返回的是函数指针
}
getNews('./Servlet/NewsServlet?newsId=1')
.then((data)=>{
    //显示内容
    displayNews(data);
    //根据上一次返回的内容,找到commentId,再次请求评论
    return getNews(data.commentUrl);
},(error)=>{
    //当状态变成rejected时调用
    console.log(error);
}).then((data)=>{
    //显示评论
    displayComment(data);
},(error)=>{
    //显示错误
    console.log(error);
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

三、async异步函数

async语法请看我另一篇文章https://blog.csdn.net/weixin_46215920/article/details/113874008

  • getNewsAsync异步函数用来平行书写获取内容和评论
  • getNews()也是用来发送ajax请求,并且返回promise对象
    async function getNewsAsync(url){
        const data = await getNews(url); // 获取新闻内容. data 接收的是 promsie解包后,resolve的实参
        displayNews(data); // 渲染新闻内容
        data = await getNews(data.commentUrl);
        displayComment(data); // 渲染评论
        
    }
    function getNews(url){
        return new Promise((resolve, reject) => {
            $.get(url, (data) => {
                resolve(JSON.parse(data));
            })
        })
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

总结

综合上面的三种ES6处理ajax异步请求,个人觉得async是最方便的,它结合了generator和Promise的实现方法,并且做了优化语法,使得逻辑更加清晰,代码可读性更高,也更好维护!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/148346?site
推荐阅读
相关标签
  

闽ICP备14008679号