promise和jsonp
ajax回顾:
核心对象: xmlhttprequest
步骤
1.创建对象
2.打开请求地址(设置请求方式 GET 和 POST)
3.发送请求
4.监听请求
5.在请求监听中获取数据
回调地狱
回调的函数的无限嵌套 导致代码的可读性和可维护性差 以及代码的可扩展性差(代码失去了价值)
//需求 从a接口里面查询 用户名是李四的id
//从b接口查询对应的id的商品
//从c接口查询对应的商品的ip的商品类型
// 伪代码
AjaxUtil.get('a',{username:'李四'},(res)=>{ //a接口通过传姓名 获取返回的id
AjaxUtil.get('b',{id:res.data.id},(res)=>{ //通过a接口返回的id 来获取对应的商品
AjaxUtil.get('c',{id:res.data.id},(res)=>{ //通过b接口返回的商品id 来获取对应的商品类型
console.log(res.data);
解决回调地狱
使用es6新增的promise对象
Promise对象
概述:
promise是es6新增的一个对象,他翻译为承诺,他有三种状态。promise设计为异步的。
等待状态 (不能做其他的事情)
成功状态 (有成功调用的方法)
失败状态 (有失败调用的方法)
示例
// 使用new关键词 里面传递的参数是一个方法 这个方法里面通常存储一些异步的操作
// resolve表示成功执行的方法 reject失败执行的方法
var promise = new Promise((resolve,reject)=>{
let timer = setTimeout(()=>{
console.log('hello');
//调用成功的方法 里面可以传参数
// resolve('成功')
reject('失败')
},2000)
})
then (resolve进入的方法)
//对应的promise对象有俩个方法 then 成功调用的方法 catch 失败调用的方法
//.then 在对应的resolve方法调用以后 .catch reject调用才能进入
promise.then((res)=>{
//在then里面的方法 里面的参数为resolve的传递的参数
console.log(res);
console.log('我执行完了');
})
catch (reject进入的方法)
promise.catch((err)=>{
//在catch里面的方法 里面的参数为reject的传递的参数
console.log(err);
})
finally (只要达到成功或者是失败调用的方法)
//不管成功还是失败都会调用的方法(没有值传递)
promise.finally(()=>{
console.log();
})
then catch finally 都是原型方法 Promise.prototype上面的方法
对象方法
Promise.reject() //返回的是一个promise对象(then获取的参数)
Promise.resolve() //返回的是一个promise对象(catch获取的参数)
Promise.all(promise数组) //返回也是一个promise数组 (并行执行 包含执行完成的)
Promise.race(promise数组) //返回的一个promise对象 (返回的是最先执行的promise)
//对象方法
Promise.reject('失败').catch((res)=>{
console.log(res);
}) //失败
Promise.resolve('成功').then((res)=>{
console.log(res);
}) //成功
var arr = Promise.all([promise1,promise2,promise3]) //当所有的执行完才返回结果(数组)
var promise4 = Promise.race([promise1,promise2,promise3]) //race竞速 谁先执行完就是谁
利用promise来解决回调地狱
1.通过在对应的.then方法里面进入返回一个新的promise对象的形式
//解决回调地狱的方案
promise1.then((res)=>{
console.log(res);
return new Promise((resolve,reject)=>{
setTimeout(()=>{
console.log('jack');
resolve('jack的promise')
},1000)
})
}).then((res)=>{
console.log(res);
return new Promise((resolve,reject)=>{
setTimeout(()=>{
console.log('吃饭了吗');
resolve('吃饭了的promise')
},1000)
})
}).then((res)=>{
console.log(res);
setTimeout(()=>{
console.log('你好');
},1000)
})
ES7新增 async(异步) await(等待)
async修饰方法 await修饰对应的promise的
1.async修饰的方法会返回一个promise对象
2.await只能在async里面使用 (他是用来修饰promise对象的)
3.await会让当前的主线程等待 (上锁)当你执行完成(成功了或者失败了)才放行(解锁)
//使用es7的 async以及await来简化代码
window.onload = async ()=>{
await new Promise((resolve,reject)=>{
setTimeout(()=>{
console.log('hello');
resolve()
},1100)
})
await new Promise((resolve,reject)=>{
setTimeout(()=>{
console.log('您好');
resolve()
})
})
console.log('执行完了');
}
使用promise封装对应的ajax
//xmlhttprequest有兼容 ie兼容 activeXObject
function initXhr(){
if(XMLHttpRequest){
return new XMLHttpRequest()
}
return new ActiveXObject("Micrisoft.XMLHTTP");//兼容ie6的
}
// 准备一个默认对象
var defaultObj = {
method:'get', //请求方式 默认为get
data:{}, //请求的数据 默认空对象
url:"", //请求的url地址 默认为空字符
dataType:"json", //请求过去的数据类型 默认为json
async:true //是否异步 默认为异步
}
//传递一个对象
//请求方式 method 请求的数据data 请求的地址 url 对应的请求的数据data-type 是否异步 async
function ajax(option={}){
//填值
for(var key in defaultObj){
//没有这个值进行填值 如果有这个就是返回本身
option[key]?option[key]:option[key]=defaultObj[key]
}
//判断地址不为空
if(option["url"]==""){
throw new Error('地址不能为空')
}
//判断请求的方法不是get获取post 报错
if(option["method"].toLowerCase()!='get' && option["method"].toLowerCase()!='post' ){
throw new Error('请求方式错误')
}
//区别 设置请求的时候 get指定(?拼接) post指定(请求体中)
let request = initXhr()
//指定请求
//如果是get先做数据拼接
if(option["method"].toLowerCase()=='get'){
//取出对应的数据进行拼接
for(let key in option["data"]){
if(option["url"].indexOf('?')!=-1){
option["url"] += `&${key}=${option["data"][key]}`
}else{
option["url"] += `?${key}=${option["data"][key]}`
}
}
request.open('get',option["url"])
//发送请求
request.send()
}else{//就是post请求
// request.setRequestHeader("Content-type","application/x-www-form-urlencoded");
request.open('post',option["url"])
request.setRequestHeader('Content-type',`application/${option["dataType"]}`)
//发送请求
request.send(JSON.stringify(option["data"]))
}
return new Promise((resolve,reject)=>{
// 监听请求
request.onreadystatechange = function(){
if(request.readyState == 4 && request.status==200){
// 返回数据
let obj = JSON.
