异步任务就是无法直接拿到结果的任务,于是我们通常会传一个回调给异步任务,异步任务完成时调用回调,调用的时候把结果作为参数传给回调。那么如果异步任务有两个结果成功或失败,怎么办呢?回调搞两个参数?或者搞两个回调?
不管方法一还是方法二,都有如下问题。
- 不规范,名称五花八门,有人用success+error,有人用success+fail,有人用done+fail
- 容易出现回调地狱,代码变得看不懂
- 很难进行错误处理
由于以上这些原因,前端程序员开始翻书了,1976年,Daniel P.Friedman和David Wise俩人提出了Promise思想,后人基于此发明了Future、Delay、Deferred等,前端结合Promise和JS,制订了Promise/A+规范,该规范详细描述了Promise的原理和使用方法。
ajax = (method,url,options)=>{
return new Promise((resolve, reject)=>{
const {success,fail} = options
const request = new XMLHttpRequest()
request.open(method,url)
request.onreadystatechange = ()=>{
if(request.readyState === 4){
if (request.status < 400){
resolve.call(null,request.response)
}else if(request.status >= 400){
reject.call(null,request)
}
}
}
request.send()
})
}
调用时只需 ajax('get','/xxx').then((request)=>{},(request, status)=>{})
我们封装的ajax很简陋,缺点是无法post上传数据,不能设置请求头…
有许多优秀的封装AJAX的库,如jQuery.ajax、axios…