我们知道程序有两种运行方式,同步和异步。
- 异步和同步
- 异步,操作之间没有关系,同时执行多个操作, 代码复杂
- 同步,同时只能做一件事,代码简单
- Promise 对象
- 用同步的方式来书写异步代码
- Promise 让异步操作写起来,像在写同步操作的流程,不必一层层地嵌套回调函数
- 改善了可读性,对于多层嵌套的回调函数很方便
- 充当异步操作与回调函数之间的中介,使得异步操作具备同步操作的接
Promise
promise适合一次读一组数据,方便。下面看看代码
传统的方式:
$.ajax({
url:'1.txt',
dataType:'json',
success(res){
console.log(res);
},
error(){
console.log('出错了')
}
})
$.ajax({
url:'2.txt',
dataType:'json',
success(res){
console.log(res);
},
error(){
console.log('出错了')
}
})
$.ajax({
url:'3.txt',
dataType:'json',
success(res){
console.log(res);
},
error(){
console.log('出错了')
}
})
promsie的方式,通过Promsie.all()
function promiseAjax(url){
return new Promise((resolve,reject)=>{
$.ajax({
url,
dataType:'json',
success(res){
resolve(res)
},
error(err){
reject(err)
}
})
})
}
Promise.all([promiseAjax('1.txt'),promiseAjax('2.txt'),promiseAjax('3.txt')])
.then(res =>{
console.log(res) //res是个数组包含3个异步的结果
},err=>{
console.log('出错:',err)
})
但是对于带有逻辑的请求,promise好像和传统的回调差不了多少。
Promise.all([promiseAjax('1.txt')])
.then(res=>{
if(//逻辑){
Promise.all([promiseAjax('2.txt')])
.then(res=>{
if(//逻辑){}
//...
},err=>{
console.log('出错:',err)
})
}
},err=>{
console.log('出错:',err)
})
这时也就很难维护了,es6中有generator生成器可以解决这个问题
generatorrunner(function * () {
let user = yield $.ajax({url: '1.txt'})
if (user.type == 'VIP') {
let items = yield $.ajax({url: '2.txt'})
} else {
let items = yield $.ajax({url: '3.txt'})
}
})
不过这种要引入runner.js,所以我们还是用自带的async和await来用同步的方式写代码
async function(){
let user = await $.ajax({url: '1.txt'})
if (user.type == 'VIP') {
let items = await $.ajax({url: '2.txt'})
} else {
let items = await $.ajax({url: '3.txt'})
}
}
await只能在async函数中用
这样代码看起来可读性高。嘿嘿。