在寫前端異步請求的時候,我們可能碰到過這種情況:在執行完異步請求後,可能又需要在成功回調之後再次執行異步請求,例如:
$.ajax({
type:"post",
success: function(){//成功回調
//再次異步請求
$.ajax({
type:"post",
url:"...",
success:function(){
.......//如此循環
}
})
}
})
這就是回調地獄,這樣的代碼既不好維護,也不能複用。
另外還有一種情況:有一個變量在另一個方法使用他之前需要異步請求並且改變他的值,例如:
var a = 1
f1()
f2()///輸出1
function f1() {
$.ajax({
type:"post",
url:"...",
success:function(){
a = 2;
}
})
}
function f2() {
console.log(a)///期望輸出2
}
當然,我們可以把請求改成同步來解決這個問題。
以上的兩種問題的情況,我們都可以用promise來解決;先看一下promise的用法:
var p1 = new Promise(f1);
var p2 = p1.then(function (result) {
///f1執行成功的回調
});
var p3 = p2.catch(function (reason) {
///f1執行失敗的回調
});
也可以簡寫爲:
new Promise(f1).then(function (result) {
///f1執行成功的回調
}).catch(function (reason) {
///f1執行失敗的回調
});
promise會在f1異步請求執行完成後,才繼續執行。這樣的好處就是如果有多個異步請求,需要先執行f1,成功後再執行f2,如果其中有任何任務失敗則不再繼續並執行錯誤處理函數,這樣就不用去寫嵌套的異步請求了。同時把執行代碼和處理結果的代碼清晰地分離。所以promise可以一下解決上面兩個問題:
var p = new Promise(f1)
.then(f2)
.then(f3)
.then(f4)
.then(f5)
.then(f5)
另外,除了串行執行異步任務外,Promise還可以並行執行異步任務:使用promise.all()
Promise.all([f1, f2]).then(function (results) {
console.log(results); // 獲得一個Array
})
我們還可以使用Promise.race()來做容錯處理、
Promise.race([f1, f2]).then(function (result) {
console.log(result); //f1和f2誰先執行成功,則先返回誰的結果;而另一個將丟棄
})