回调是地狱是容易遇到的坑,解决方案是使用promise
碎碎念
相信各位玩家肯定都写过下面的这样代码:
// 同时发送两个请求
let url = 'xxxxx', url1 = 'xx'
$.ajax({
url,
success(data) {
$.ajax({
url: url1,
success(data) {
console.log('done')
}
})
}
})
是不是很贴切?
有可能有的新手小伙伴连回调
都不知道,这里给大家普及一下
/*
** time - 时间
** call - 回调
*/
let outTime = (time, call) => {
setTimeout(()=> {
call()
}, time)
}
// 使用
outTime(2000,()=>{
console.log('done')
})
这就是最简单最常见场景下的回调了. 在我刚学js
时候,遇到一个困惑
在尝试发起请求的时候, 第一会遇到跨域请求, 还有就是不是同步代码的困惑
所谓的同步代码,给大家上一段当初我写的代码(超害羞??)
// 假设我封装了一个方法来发起`http`请求: func
let data = func({
url: 'xxx',
data: { path: 'xxx' }
})
console.log(data)
当打印之后永远都是undefined
诶,我就不信了
func({
url: 'xxx',
data: { path: 'xxx' },
success(data) {
window.fuck = data
}
})
let fuckInter = setInterval(()=> {
if (window.fuck) next()
},50)
function next() {
// 接下来的代码..
}
先别笑,我当初还真是这么解决的..
我尝试读了一下jq
源码,发现它实现了一种所谓的callback
回调函数
(很惭愧的是,现在都不能跟观众老爷们说明白这是怎么一回事)
通过这件事,让我想起我一次面试,我面的是小程序,以下对话
Ta: 小程序的网络请求不太完善,你有什么办法能够优化一下网络库,满足自己需求
Me: 写一个公共文件,写一个回调函数, 把需要的参数这些都包裹起来并封装
Ta: (内心一团乱麻..) 还有...有吗?
Me: (又说了一遍)
Ta: 那好像和微信的原生库没什么区别
被小瞧了,那货其实是想问,请求加密之类的,我说用token
(你又没说功能,我怎么知道...)
解决方案
回到正题,接下来就说解决方案了
vuejs
官方推荐的 axios
就是使用 promise
, 我有幸在几个项目中使用过,但是没有深究其原理
;(async ()=> {
return new Promise(( rcv, rjt)=> {
setTimeout(()=> {
rcv('fuck')
}, 5000)
})
})()
.then(r=> {
console.log(r) // 'fuck'
})
promise
接受两个参数: resolve, reject
第一个参数是操作成功,第二个是在操作错误
值得一提的,如果你打印这个对象的话,它返回的会是一个:
let pro = new Promise((rsv,rjt)=> {
console.log('xxx')
})
console.log(pro)
/*
** Promise { pending(进行中)、fulfilled(已成功)和 rejected(已失败)}
**/
在实例创建后,你可以使用then
来处理成功catch
来处理操作错误
现在我们就可以使用它来重写$.ajax
方法
function proAjax() {
let url = 'xxx' // 假装存在咯
return new Promise((rcv, rjt)=> {
$.ajax({
url,
success: data => rcv(data),
error: e=> rjt(e)
})
})
}
// 用法
proAjax()
.then(r=> {
console.log('我拿到数据了,真好')
})
.catch(e=> {
throw new Error(e)
}
为了让它更像同步代码,我们可以使用async
await
async function func() {
let data await new Promise((rcv,rjt)=> {
$.ajax(
url,
success: data => rcv(data)
)
})
return data
}
func()
.then(r=> {
console.log('拿到数据了,皮卡丘!')
})
async
我不太能够解释这是什么,只知道它会返回一个promise
,所以它有then
| catch
方法,至于await
它只能在async
函数里使用,它可以获取promise
返回值(这里不知道怎么表达),就可以实现所谓的同步代码
报错信息也很有用哦
总结
这货解决了回调地狱
, 在本篇文中并未提及在promise
下的多"回调",不过在每次then
下由可以return promise
对象,接下来就你懂的~
拥抱新技术,拥抱开源
20190819
原文地址:https://www.cnblogs.com/kozo4/p/11379873.html