我个人理解Promise Async Await 是为了解决复杂异步操作出现的,有了这三者复杂的异步操作变的很简单。举个例子啊:多级嵌套请求,前端向服务器请求数据,第二次请求依赖第一次请求的数据,第三次请求依赖第二次请求的数据,第四次请求依赖第三次请求的数据...
没有Promise之前的写法,代码如下:
/**
* @method 对ajax进行封装
* @param {{}} config 用于ajax的配置信息
* @param {function} success 成功取得数据的调用方法
* @param {function} err 没取得数据的调用方法
*/
function methodA(config,success,err){
//对config进行一些配置,如果url或param或type没写啊,给个默认值
let trueConfig = Reconfig(config);
$.ajax({
url: trueConfig.url,
data: trueConfig.param,
type: trueConfig.method,
success: function (data) {
success(data);
},
error: function (err) {
err(err)
}
})
}
methodA({url:'http://a.com'},function(data){
//对第一次请求到的数据进行处理
let a = data%2
//进行第二次请求,并将a传入
methodA({url:'http://b.com',param:{ip:a}},function(data){
//对第二次请求到的数据进行处理
let b= data*2c
//进行第三次请求,并将b传入
methodA({url:'http://c.com',param:{city:b}},function(data){
//对第三次请求到的数据进行处理
let c =data/2d
//进行第四次请求,并将c传入
methodA({url:'http://d.com',param:{mony:c}},function(data){
//...依次类推
})
})
})
})
/**
* @method 对config进行初始化,当config没有传入对应参数时,给个默认值
* @param{Object} config 请求数据的地址,参数,方法等信息
* @param{String} config.url 请求数据的地址
* @param{Object} config.param 请求的参数信息
* @param{String} config.type 请求的类型,"GET","POST"等
*/
function Reconfig(config){
let Reconfig ={url:'',param:{},type:'GET'}
for (const key in config) {
Reconfig[key]=config[key]
}
return Reconfig;
}
当然实际开发中,逻辑不会这么简单,有木有感觉特别复杂,一层嵌套一层,都分不清哪个是参数处理方法,哪个请求是哪个请求了,这还没写,请求错误的方法。写出来感觉更乱
有了Promise 之后的写法,代码如下:
//同上对ajax进行封装
function methodB(config) {
let trueConfig = Reconfig(config)
return new Promise((resolve, reject) => {
$.ajax({
url: trueConfig.url,
data: trueConfig.param,
type: trueConfig.method,
success: function (data) {
//执行resolve会将Promise标记为fulfilled(成功),随后调用.then()方法,会执行then方法中传入的方法,并将data传入
resolve(data)
},
error: function (err) {
//执行resolve会将Promise标记为rejected (成功),随后调用.catch()方法,会执行catch方法中传入的方法,并将err传入
reject(err)
}
})
})
}
//进行第一次请求
methodB({ url: 'http://a.com'}).then((data) => {
//对第一次请求的数据进行些处理
let a = data % 2
//进行第二次请求,并将a传入
return methodB({url:'http://b.com',param:{ip:b}})
}).then((data)=>{
//对第二次请求的数据进行处理
let b = data*2
//进行第三次请求,并将b传入
return methodB({url:'http://c.com',param:{city:b}})
}).then((data)=>{
//对第三次请求的数据进行处理
let c = data/2
//进行第四次请求,并将c传入
return methodB({url:'http://d.com',param:{mony:c}})
}).then((data)=>{
//...依次类推
}).catch(console.log)
是不是感觉要简单点了,不再是一层嵌套一层,看着要好多了。而且当请求不到数据时,执行reject()后,执行.then()方法,then方法中传入的方法不会执行,且返回已经标记为rejected的Promise,直到遇到catch()会执行catch中传入的方法对错误进行处理。
Async,Await是Promise的语法糖,有了它们,代码更简单,代码如下:
//对ajax的封装部分就不再写了,和有Promise的写法一样
//定义一个函数用于请求数据,函数前加async修饰符
async function getData(){
//进行第一次请求,当成功时会将得到的数据赋值给data1
let data1 = await methodB({ url: 'http://a.com'})
//对第一次请求到的数据进行处理
let a = data1 % 2;
//进行二次请求,并将a传入 成功时会将得到的数据赋值给data2
let data2 = await methodB({url:'http://b.com',param:{ip:a}})
//对第二次请求到的数据进行处理
let b = data2*2
//进行第三次请求,并将b传入 成功时会将得到的数据赋值给data3
let data3 = await methodB({url:'http://c.com',param:{city:b}})
//对第三次请求到的数据进行处理
let c = data3/2
//进行四次请求,并将c传入 成功时会将得到的数据赋值给data4
let data4 = await methodB({url:'http://d.com',param:{mony:c}})]
//以此类推
}
是不是更简单了,.then都省掉了,Async 和 Await 是Promise的语法糖,Await必需与Async一起使用,否则没有作用。如果看了本篇文章,对Promise,Async,Await还不是特别理解,可以参照 MDN上面的解释 developer.mozilla.org/zh-CN/docs/…