基礎用法
promise有三種狀況:pending(舉行中)、fulfilled(已勝利)和rejected(已失利),Promise組織函數吸收一個函數作為參數,該函數的兩個參數離別是resolve和reject,个中resolve函數會將pending狀況改成fulfilled,reject函數將pending改成rejected狀況,狀況一旦轉變,將不可逆。這兩個函數的函數的參數將會傳給回調函數
const promise = new Promise(function(resolve, reject) {
// ... some code
if (/* 異步操縱勝利 */){
resolve(value);
} else {
reject(error);
}
});
promise.then((value)=>{
console.log(value)
},(error)=>{
console.log(error)
})
then要領
Promise實例天生今後,能夠用then要領離別指定resolved狀況和rejected狀況的回調函數,第一個是狀況由pending->fulfilled的回調,第二個是pending->resolved的回調。
then為何能夠舉行鏈式挪用呢?緣由就是then要領返回的也是一個promise對象,所今背面能夠繼承運用then()要領。
此處有個處所須要注重,偏重明白下面這句話:
Values returned from the onFulfilled or onRejected callback functions will be automatically wrapped in a resolved promise.
then()的兩個參數函數中返回的值,會自動包裝成一個已resolved的promise。
代碼1:
$http({
method: 'GET',
url: 'https://www.runoob.com/try/angularjs/data/sites.php1'
}).then(function successCallback(data_1) {
$scope.res = data_1;
$scope.names = data_1.data.sites;
return data_1;
},function (err_1) {
console.log("err_1",err_1);
return err_1;
}).then(function (data_2) {
console.log("data_2", data_2)
},function (err_2) {
console.log("err_2---->",err_2);
}).catch(function (reason) {
console.log("err------->",reason);
});
注:$http返回的是一個promise對象。
效果以下:
收集要求404->失利的回調函數err_1要領->勝利的回調函數(why),緣由就是then中的回調函數,無論是勝利回調照樣失利回調,他們return的值都會被包裝成promise的對象的resolved函數來處置懲罰,從而會傳遞給下一個then要領的勝利回調函數內里去。
代碼2:
Promise.resolve()
.then(() => {
return new Error('error!!!')
})
.then((res) => {
console.log('then: ', res)
})
.catch((err) => {
console.log('catch: ', err)
})
效果是:
then: Error: error!!!
at Promise.resolve.then (...)
at ...
緣由是:.then 或許 .catch 中 return 一個 error 對象並不會拋出毛病,而是經由過程resolved來處置懲罰的,所以不會被後續的 .catch 捕獲,須要改成个中一種:
1.return Promise.reject(new Error('error!!!'))
2.throw new Error('error!!!')
catch要領
Promise.prototype.catch要領是.then(null, rejection)的語法糖,用於指定發作毛病時的回調函數。
1.then要領中沒有第二個失利回調函數,當reject后,會進入catch要領;若then要領有第二個失利
回調,則reject後會進入此函數,而不會進入catch要領。
$http({
method: 'GET',
url: 'https://www.runoob.com/try/angularjs/data/sites.php'
}).then(function successCallback(data_1) {
$scope.res = data_1;
$scope.names = data_1.data.sites;
return data_1;
},function (err_1) {
console.log("err_1",err_1);
return err_1;
}).catch(function (reason) {
console.log("err------->",reason);
});
效果:
當沒then有第二個回調函數,則會進入catch要領。
小疑問:catch要領中return一個數值,在其背面的.then()的勝利回調中會吸收到么?答案是會的,把catch看做成沒有勝利回到的.then(),其return的數值也會被resolved出去。
注重:不要在then要領內里定義 Reject 狀況的回調函數(即then的第二個參數),老是運用catch要領。理由是第二種寫法能夠捕獲前面then要領實行中的毛病,也更靠近同步的寫法(try/catch)
// bad
promise
.then(function(data) {
// success,標記1.如果在此處代碼拋出了毛病,此then函數的失利回調函數是捕獲不到的。
}, function(err) {
// error
});
// good
promise
.then(function(data) { //cb
// success
})
.catch(function(err) {
// error
});
即:如果在“標記1”出代碼拋出毛病,背面的失利回調函數是捕獲不到的(只能捕獲上一個promise對象拋出的毛病,本身所處在的then中是捕獲不到的),而只能被下一個then函數的失利回調(也就是catch)捕獲到。
例子:
Promise.resolve()
.then(function success (res) {
throw new Error('error')
}, function fail1 (e) {
console.error('fail1: ', e)
})
.catch(function fail2 (e) {
console.error('fail2: ', e)
})
效果:
fail2: Error: error
at success (...)
at ...
.then 能夠吸收兩個參數,第一個是處置懲罰勝利的函數,第二個是處置懲罰毛病的函數。.catch 是 .then 第二個參數的輕便寫法,然則它們用法上有一點須要注重:.then 的第二個處置懲罰毛病的函數捕獲不了第一個處置懲罰勝利的函數拋出的毛病,而後續的 .catch 能夠捕獲之前的毛病
以下代碼也能夠:
Promise.resolve()
.then(function success1 (res) {
throw new Error('error')
}, function fail1 (e) {
console.error('fail1: ', e)
})
.then(function success2 (res) {
}, function fail2 (e) {
console.error('fail2: ', e)
})