赞
踩
setTimeout(console.log, 0, 1);
console.log(2);
// 2
// 1
这里,定义了一个setTimeout(),0ms后执行console.log(1),他的等待时间是0,并且它在console.log(2)前面。正常理解应该是先输出1,再输出2,但是并不是。这是因为setTimeout是异步执行函数,console.log是同步执行函数,在运行到setTimeout时,js引擎会把他先放进一个任务队列中,先不执行,接着运行console.log(2),直接输出控制台,同步函数执行完后再执行任务队列中的console.log(1)
// 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);// 展示新闻评论 }) }
{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语法请看我的另外一篇文章
https://blog.csdn.net/weixin_46215920/article/details/113869165
// 利用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); // 展示评论 }) }
Promise语法请看我另一篇文章https://blog.csdn.net/weixin_46215920/article/details/113872957
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); })
async语法请看我另一篇文章https://blog.csdn.net/weixin_46215920/article/details/113874008
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));
})
})
}
综合上面的三种ES6处理ajax异步请求,个人觉得async是最方便的,它结合了generator和Promise的实现方法,并且做了优化语法,使得逻辑更加清晰,代码可读性更高,也更好维护!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。