1.先说说Promise对象
Promise是ES6中处理异步操作的一个新方式,Promise对象有三种状态:Pending(进行中)、Resolved(已完成,又称 Fulfilled)和 Rejected(已失败),写法如下:
//1)创建promise对象,创建后立刻执行
//接收一个函数作为参数,resolve、reject是Promise状态发生变化时执行的函数,这里由js引擎渲染出,不需要手动定义。
var promise = new Promise(function(resolve,reject){
setTimeout(()=>{
let num = parseInt(Math.random()*10)
if(num%2){
resolve(0)
}else{
reject(1)
}
},500)
})
//2)状态改变时的调用
promise.then(suc=>{
//执行上面的resolve()
console.log(`奇数;${suc}`)
},err=>{
//执行上面的reject()
console.log(`偶数;${err}`)
})
2.async function
async函数是ES7的内容,async函数可以看作是将异步操作包装成的一个 Promise 对象,而await命令就是内部then命令的语法糖,语法非常的简单明了。
await 命令后面是一个promise对象,或者是其他异步进程。await 表达式会暂停当前 async function 的执行,等待 Promise 处理完成。如果Promise 正常处理(fulfilled),其处理结果作为 await 表达式的值,继续执行 async function;如果 Promise 处理异常,则异常值被抛出,整个函数停止执行
//定义一个异步函数
async getData(i){
let res;
try(){
//await 暂停当前函数的执行,直到异步进程处理完成
res = await axios.get(`../../static/data${i}.json`)
}catch(e){
res = e
}
return res
}
async函数返回一个promise对象,函数内部return的值可以作为then方法回调函数的参数。
getData(0).then(res=>{
console.log(res)
})
3.并发问题
await关键字会暂停函数的执行,但不会阻塞进程
下面这种写法,三个请求依次触发
async function getNum_1() {
for(let i = 0; i < 3; i++){
console.log(`%c start${i}`, "color:green")
//暂停执行,等待结果
let res = await axios.get(`../../static/data${i}.json`)
//获得结果,处理结果 并 进入下一次循环
console.log(res.data.msg)
}
}
正确的写法是这样:
function getNum_2(){
for(let i=0; i<3; i++){
//循环调用上文中的async函数,多个异步函数并发,不会阻塞进程
this.getNum(i)
}
}
或者使用Promise对象的all方法
//1)使用map方法创建promise对象数组
let promises = [0,1,2].map((i)=>{
return this.getNum(i) // 执行async函数,返回promise对象
})
//2)处理异步结果
Promise.all(promises).then((res)=>{
//所有异步方法完成后调用
console.log('done')
})