异步操作常见于ajax数据读取等
ajax基本写法:
ajax('http://aaa.com/a/1.txt',function(){
//成功
}[
,function(){
//失败
}]
)
异步操作:可以同时进行多个操作,用户体验好;代码混乱
ajax('http://taobao.com/api/user',function(data1){
ajax('http://taobao.com/api/items',function(data2){
ajax('http://taobao.com/api/ad',function(data3){
},function(){
alert('error')
})
},function(){
alert('error')
})
},function(){
alert('error')
})
同步操作:一次只能进行一个操作,用户体验不好;代码清晰
let data1 = ajax('http://taobao.com/api/user');
let data2 = ajax('http://taobao.com/api/items');
let data3 = ajax('http://taobao.com/api/ad');
两种都有各自的优缺点,那么可不可以融合他们的优势呢,让代码写起来既方便,也能运行高效
有两种方式:
- Promise
- async/await
Promise----主要是封装异步操作,而不是处理异步操作
基本写法:
let p = new Promise(function(resolve,reject){
//异步操作
//resolve--解决 成功
//reject--拒绝 失败
$.ajax({
url:'data/1.txt',
dataType:'json',
success(arr){
resolve(arr);//Promise不负责处理 交给外部来处理
},error(resp){
reject(resp);
}
})
})
// then()第一个参数对应Promise的resolve函数,第二个参数对应reject函数
p.then(function(arr){
alert(arr)
},function(resp){
alert('失败了')
console.log(resp)
})
不能说Promise对象的作用只是封装,它也有自己简单的处理异步操作的方法,如Promise.all()
Promise.all()方法要求所有需要读取的数据都读取完(都成功读取到)之后,返回一个统一的结果
Promise.all([
new Promise1,
new Promise2,
new Promise3,
...
]).then(function(){
//成功
},function(){
//失败
})
例:
Promise.all([
$.ajax({url:'data/1.txt',dataType:'json'}),
$.ajax({url:'data/2.txt',dataType:'json'}),
$.ajax({url:'data/3.txt',dataType:'json'})
]).then(arr=>{//arr是个数组 或者写成 [data1,data2,data3](解构赋值) 一定要带'[]'
let [data1,data2,data3] = arr;//解构赋值 或者直接在接收参数的时候就完成
console.log(data1,data2,data3);
},resp=>{
console.log(resp)
})
注意:
jQuery的ajax本身就是一个Promise对象
let resp = $.ajax({
url:'data/1.txt',
dataType:'json'
})
console.log(resp);//Promise对象
所以说其实不需要用Promise去封装ajax,这只是为了方便理解,可以直接使用ajax
$.ajax({
url:'data/1.txt',
dataType:'json'
}).then(arr=>{//成功 返回arr数据
alert(arr);
},resp=>{//失败 返回失败信息resp
alert('失败');
})
Promise对象还有一个方法,Promise.race()<不常用>
Promise.race()也是同时读取个数据,但是谁先完成就用谁,成功函数只返回一个结果;如果都读取失败,执行失败函数,返回失败信息
async/await(取代了generator/yield)----函数的特殊形式
基本写法:
async function show(){//asynd语法写在函数前面 声明该函数中包含异步操作
xxx;
xxx;
let data = await $.ajax();//表明这是个异步操作,函数执行到这里要'等待',等这步运行完函数才能继续往下运行
xxx;
}
show();
普通函数和async函数的区别:
- 普通函数:只要开始运行,就会一直执行,直到函数结束
- async函数:能够’暂停’,
async/await
是个语法糖,会将函数内部拆分成多个小函数,在每个小函数内部也是按照普通函数的执行过程来执行的
例:
async function show(){
let a = 12;
let b = 5;
let data = await $.ajax({
url:'data/1.txt',
dataType:'json'
})
alert(a+b+data[0]);
}
show()//29
相当于内部按照await
的位置分成:
function show_1(){
let a = 12;
let b = 5;
}
$.ajax({
url:'data/1.txt',
dataType:'json'
}).then(function(){
show_2();
})
function show_2(){
alert(a+b+data[0]);
}
虽然这种写法看起来和写起来和同步操作相似,但内部实际上是异步操作
但这种写法无法捕获异常,要使用js里的try/catch
语法来捕获
async function show(){
let a = 12;
let b = 5;
try{
let data = await $.ajax({
url:'data/1.txt',
dataType:'json'
})
alert(a+b+data[0])
}catch(e){
alert('读取失败');
}
}
show();