我們知道程序有兩種運行方式,同步和異步。
- 異步和同步
- 異步,操作之間沒有關係,同時執行多個操作, 代碼複雜
- 同步,同時只能做一件事,代碼簡單
- 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函數中用
這樣代碼看起來可讀性高。嘿嘿。