Promise 概述
Promise 是異步編程的一種解決方案,從語法上講,Promise 是一個對象,從它可以獲取異步操作的消息。
優(yōu)點:
- 可以避免多層異步調(diào)用嵌套問題(回調(diào)地獄)
- Promise 對象提供了簡潔的 API,使得控制異步操作更加容易
Promise基本用法
- 實例化 Promise 對象,構(gòu)造函數(shù)中傳遞函數(shù),該函數(shù)中用于處理異步任務
- resolve 和 reject 兩個參數(shù)用于處理成功和失敗兩種情況,并通過 p.then 獲取處理結(jié)果
var p = new Promise(function(resolve,reject){
//實現(xiàn)異步任務...
//成功時調(diào)用
resolve();
//失敗時調(diào)用
reject();
});
p.then(function(ret){
//從resolve得到正常結(jié)果
},function(ret){
//從reject得到錯誤信息
});
基于 Promise 處理 Ajax 請求
- 處理原生 Ajax
function queryData(url){
return new Promise(function(resolve,reject){
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if(xhr.readyState!=4) return;
if(xhr.status == 200){
resolve(xhr.responseText);
}else{
reject('出錯了');
}
}
xhr.open('get',url);
xhr.send(null);
});
}
//調(diào)用
queryData('http://localhost:3000/data').then(
function (data) {
console.log(data);
},
function (data) {
console.log(data);
}
)
- 發(fā)送多次 ajax 請求(解決回調(diào)地獄)
queryData('http://localhost:3000/data')
.then(function (data) {
console.log(data);
//異常情況可以不處理
return queryData('http://localhost:3000/data1');
})
.then(function (data1) {
console.log(data1);
return queryData('http://localhost:3000/data2');
})
.then(function (data2) {
console.log(data2);
});
then參數(shù)中的函數(shù)返回值
- 返回 Promise 實例對象返回的該實例對象會調(diào)用下一個 then
- 返回普通值返回的普通值會直接傳遞給下一個 then,通過 then 參數(shù)中函數(shù)的參數(shù)接收該值
Promise常用的API
1.實例方法
* p.then()得到異步任務的正確結(jié)果
* p.catch()獲取異常信息
* p.finally()成功與否都會執(zhí)行(暫時還不是正式標準)
foo()
.then(function (data) {
console.log(data);
})
.catch(function (data) {
console.log(data);
})
.finally(function () {
console.log('finish');
})
也可以寫為:
foo()
.then(function (data) {
console.log(data);
},
function (data) {
console.log(data);
})
.finally(function () {
console.log('finish');
})
2.對象方法
- Promise.all() 并發(fā)處理多個異步任務,所有任務都執(zhí)行完成才能得到結(jié)果
//p1,p2,p3為Promise實例對象任務
Promise.all([p1,p2,p3]).then((result)=>{
console.log(result);
})
- Promise.race()并發(fā)處理多個異步任務,只要有一個任務完成就能得到結(jié)果
Promise.race([p1,p2,p3]).then((result)=>{
console.log(result);
})