什么是Promise 简单来说就是用来统一,封装异步操作的,可以使你以同步的方式去做异步的事情,简化了异步操作的不断的回调
既然Promise是统一异步操作的那么首先我们得知道什么是异步 异步通俗来讲就是,你做你的,我做我的我们之间互不影响,如js中的Ajax
我们先来看以前的异步操作的缺陷,以jq的ajax为例 下面示例发送了3次ajax请求,因为我的请求是有顺序的,我们等第一个ajax请求成功后在执行第二个请求,以此类推。
代码语言:javascript复制$(function(){
$.ajax({
url:'1.json',
datatype:'json',
success:function(one){
$.ajax({
url:'2.json',
datatype:'json',
success:function(two){
$.ajax({
url:'3.json',
datatype:'json',
success:function(three){
console.log(one,two,three)
}
})
}
})
}
})
})
就上面的代码看上去已经很乱了,如果请求很多咋办?难得要一直嵌套在success里面?这样也显得太麻烦了,而且不易维护。es6中的promise就是为了解决这个问题应运而生
上面说到Promise是用来统一封装异步操作的 他的基本用法是这样
代码语言:javascript复制p = new Promise(function(resolve,reject)){
//异步操作...
resolve();//成功回调
reject();//失败回调
}
p.then(function(){'resolve'},function(){'reject'})
//then方法用于异步操作返回数据后调用,成功执行resolve失败失效reject
//失败回调
p.catch((err)=>{
)
//成功失败都执行
p.finally(()=>{
})
**直接使用resolve与reject**
Promise.resolve(5).then(v=>console.log(value))
JQ的ajax是支持promise所以我们跳过他的基本用法,promise最主要的是他的高级用法 这里通过promise.all([])
解决上面无限回调的问题
Promise.all([
//等待所有异步操作完成后统一返回then
$.ajax({url:'1.json',datatype:'json'}),
$.ajax({url:'2.json',datatype:'json'}),
$.ajax({url:'3.json',datatype:'json'}),
]).then(function(arr){
console.log(arr)
},function(err){
console.log(err)
})
Promise.race 只要有一个返回结果就立即执行
代码语言:javascript复制var p1 = Promise.resolve('1')
var p2 = Promise.resolve('2')
let arr = [p1,p2]
var result = Promise.race(arr)
result.then(function(res){
console.log(res)
})
then的第一个参数就是resolve
他会等all里面的所有异步执行完毕后执行,中途有一个请求失败则返回then的第二参数reject
,通过这样的操作我们就完成了同步的语法执行异步的事情 不用一直无限回调。
这种方式看似解决了问题,但是如果我后面的ajax需要前面的ajax数据怎么办?没有了回调操作就无法在异步的过程中使用前面ajax的数据,因为他会等待所有异步操作全部执行完毕返回then
这里我们就要引入一个新的东西 es7的async/await
async和await
配合promise实现真正的以同步的语法去做异步的事情 基本语法 在fn函数通过async
关键字说明fn可以进行异步操作,函数体通过await
来指定某个Promise完成后才执行下面的代码
async function fn(){
//函数体可写异步操作
let a = await Promise对象
let a = await Promise对象
let a = await Promise对象
}
到这里我们就可以通过async和await
解决上面的问题
async function show(){
let data1 =await $.ajax({url:'1.json',datatype:'json'});
if(data1.name=='a'){
console.log('执行a')
let data2 =await $.ajax({url:'2.json',datatype:'json'});
}else{
console.log('执行b')
let data3 =await $.ajax({url:'3.json',datatype:'json'})
}
}
show();//执行a
这种方式就可以实现同步语法执行异步,并且后面的ajax可以应用前面ajax的数据,而不用像以前无限的回调。
实际上他的底层还是各种的回调,就像这样
代码语言:javascript复制let data1 = $.ajax({
url:'1.json',
datatype:'json',
success:function(){
if(data1.name=='a'){
console.log('执行a')
let data2 =await $.ajax({url:'2.json',datatype:'json'});
}else{
console.log('执行b')
let data3 =await $.ajax({url:'3.json',datatype:'json'})
}
});