Promise
由CommonJS社区提出,在ES2015中被标准化,成为语言js规范
解决回调函数嵌套问题,更好的实现异步编程,使代码扁平化
基本用法
Promise 构造函数只有一个参数,是一个函数,构造之后函数会直接被异步放到线程最后运行,所以我们称之为起始函数。异步函数执行结束后包含两个状态回调,成功执行resolve(data)回调,失败 reject(error)
function ajax(url,data){
return new Promise((resolve,reject)=>{
let xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
resolve(xmlhttp.responseText)
}else{
reject('出错')
}
}
xmlhttp.open("GET",url + "?id=" + data.id,true);
xmlhttp.send();
})
}
ajax('/user').then(res=>{
console.log(res)
})
.catch(err=>{
console.error(err)
})
链式调用
串联执行异步调用,用来避免回调嵌套
ajax('/user')
.then(val=>{
return ajax('/list',{id:val.id})
})
.then(val=>{
console.log(val)
})
.catch(err=>{
console.log(err)
})
并行处理
Promise.all()所有任务结束后返回
Promise.race()第一个任务结束后返回
ajax('/user')
.then(val=>{
return ajax('/list',{id:val.id})
})
.then(val=>{
console.log(val)
})
.catch(err=>{
console.log(err)
})
let p = Promise.all([
ajax('/menu'),
ajax('/user')
])
//所有请求完成后执行
p.then(res=>{//都成功后才会执行
console.log(res) //res是个数组保存了每个promise对象的结果
})
.catch(err=>{//有一个失败就执行
console.log(err)
})
let timeout = new Promise((resolve,reject)=>{
setTimeout(()=>reject('超时'),500)
})
let pRace = Promise.race([
ajax('/menu'),
timeout
])
//第一个任务结束后返回
p.then(res=>{//只返回第一个完成任务的处理结果
console.log(res)
})
.catch(err=>{
console.log(err)
})
Async
async是ES7 中的关键字
async函数返回一个Promise对象
await 操作符用于等待一个 Promise 对象, async function 内部才可以使用,后面也可跟其他值只是会立即返回
async function testAsync(){
let a1 = await ajax('/menu')
console.log(a1)
let a2 = ajax('/user')
console.log(a2)
let a3 = await '我是第二个'
console.log(a3)
}
testAsync()
//返回a1执行结果
//返回a3 '我是第二个'
//返回a2执行结果