重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
通过第四篇文章
创新互联公司是专业的海西网站建设公司,海西接单;提供成都网站设计、做网站,网页设计,网站设计,建网站,PHP网站建设等专业做网站服务;采用PHP框架,可快速的进行海西网站开发网页制作和功能扩展;专业做搜索引擎喜爱的网站,专业的做网站团队,希望更多企业前来合作!
《零基础通过Ajax实现网易云音乐数据交互》的学习。
我们实现了使用ajax对远程api接口的使用,但是遗留下了一个问题,就逻辑上存在前后顺序的时候造成回调地狱的情况,比如
首先通过发送用户名和密码获取用户id,根据用户id获取用户的歌单,根据用户歌单获取用歌曲名字,层层嵌套,
如下为代码所示:
getUserid(){
getSonglist(){
getSongName(){
//dom拼接
orgDom(){
}
}
}
};
大家会发现代码层层嵌套非常难维护,如下图所示:
这就是回调地狱,大家看到这个似乎想到了jquery的链式操作,
要是这样,不就很美好了嘛?
getUserid(). getSonglist().getSongName().orgDom();
这样不就变成一根绳上的蚂蚱了吗?对,这就是Promise出现的原因,让嵌套变成链式。
这里有一个很明显的误区,很多人总是觉得promise跟ajax一样是用来请求数据的,其实这是错的,
这就好比很多人把github理解成git一样,github是git的典型应用场景,两者是没办法画等号的,同样,
promise使用的经典场景就是数据交互,但是不代表数据交互和promise画等号。
说到数据交互,promise配合着fetchApi用简直是完美。
那么fetchApi又是什么呢?别被单词吓到,我保证你用它的时候不会再想用ajax。俗话说的好,ajax就像你的前女友一样,该忘就忘吧。
有人说忘不了前女友的原因只有两个,时间不够长,现任不够好。其实他们这么说只是对了一半,前提是得有人给你介绍一个足够好的现任,你的幸福生活就要来了,fetchApi就是那个出来时间已经足够长,而且对你特别好的现任。
ajax的复杂和代码不分离,相信已经让你很不爽了,那么我们看fetchApi怎么样。一言不合就上代码。来,一起回忆一下你跟你前女友吵架时候她狰狞的样子。
// 获取 XHR 非常混乱!
if (window.XMLHttpRequest) { // Mozilla, Safari, ...
request = new XMLHttpRequest();
} else if (window.ActiveXObject) { // IE
try {
request = new ActiveXObject('Msxml2.XMLHTTP');
}
catch (e) {
try {
request = new ActiveXObject('Microsoft.XMLHTTP');
}
catch (e) {}
}
}
// 打开连接, 发送数据.
request.open('GET', 'https://davidwalsh.name/ajax-endpoint', true);
request.send(null);
ok,看看现任的温柔。
// fettchApi做事很有条理
fetch('/some/url').then(function(response) {
return //... 执行成功, 第1步...
}).then(function(returnedValue) {
// ... 执行成功, 第2步...
}).catch(function(err) {
// 中途任何地方出错...在此处理,有事回家说
});
对对,就是这么优雅,我知道你想啥,我有些功能想实现怎么办呢?
var request = new Request('www.xxx.com', {
method: 'POST',
mode: 'cors',
redirect: 'follow',
headers: new Headers({
'Content-Type': 'text/plain'
})
});
// 用起来
fetch(request).then(function() { /* handle response */ });
我怎么知道她啥想法,我想知道她怎么想的怎么办?
fetch('url/')
.then(function(responseObj) {
console.log('status: ', responseObj.status);
});
人家是个好姑娘,你只要还按照之前的跟你女朋友的方式跟人家处就行了。
那么问题来了,说的挺好,问题是跟promise啥关系?我先不说咱们先看看,
//构建Promise
var promise = new Promise(function (resolve, reject) {
if (/* 异步操作成功 */) {
resolve(data);
} else {
/* 异步操作失败 */
reject(error);
}
});
promise.then(function() {
console.log('resolved');
}).then(function() {
console.log('resolved');
}).catch(){
挂了
};
promise可以把异步操作的内容扔到外面去处理。你看到then不觉的眼熟吗?
fetch是基于Promise设计的,从上面代码也能看得出来,这就要求fetch要配合Promise一起使用。正是这种设计使代码语法简单,更加语义化,逻辑也更清晰,避免层层嵌套,支持async/await
等等,这里有个问题,咋个情况,你说过promise不是半吊子嘛,另外async/await,这又是啥?
我们思考一下,问题根源是层层嵌套,然后我们考虑改成一条绳上的蚂蚱,总感觉哪里不对。
好,我们缕缕哈。假如你有一个前女友,刁钻刻薄又爱花钱,然后分手了以后,你想找个通情达理,精明能干的。然后你发现隔壁家的邻家女孩,人很乖巧,重点是不爱花钱,你觉好追,然后努力去追她了。现在大家明白了问题在哪了吧?你本来喜欢的是通情达理,精明能干的,最后你却找了一个乖巧听话的。还不明白,好,我们翻译成技术语言。
因为层层嵌套,让我们很难维护代码,然后我们想像平常写js代码一样,一步步按照顺序往下撸代码,然后你发现promise不错,他能链式操作,也挺好。问题是我们的初心忘了嘛?
你不是想像写同步代码一样撸代码吗?
有同学会说,有的用就不错了,这就挺好了。但是你要明白,就是那些不将就的人,才给你带来了promise,同样那些不将就的人也带来了异步接近完美的解决方案async/await。
下节课我们就重点说说这个async/await,有同学可能又说了,那老师墨迹个啥,直接讲async/await不就行了,这篇文章我不是白看了?
错!async/await 内部的实现也是Promise,没有这节课的东西,你根本不会明白下节课的东西。
最后一句话,永远不要因为走了太久而忘了为什么出发,更不要因为只盯着目标而忘记了看脚下的路。
·END·