上篇 談談Promise那點事(一)已經談談了Promise的基礎的知識 下面來嘮嘮實際應用的誤區
上程式碼來看看 是否在平常遇到過
- 沒有返回值
function fn () {
return new Promise (function (resolve, reject) {
if () {
//操作成功
} else {
//操作失敗
}
})
}
fn().then(function(data1) {
load(data1)
}).then(function(data2) {
load(data2)
})複製程式碼
Promise 能夠讓我們在回撥函式中return 所以then中可以return一個Promise物件或者普通物件 這樣在在後面then的回撥中是接受不到上一個load 執行的結果 因為沒有return 現在都是undefined
所以在then中一定要return 或者throw
- 沒有Catch
function fn () {
return new Promise (function (resolve, reject) {
if () {
//操作成功
} else {
//操作失敗
}
})
}
fn().then(function(data1) {
reuturn load(data1)
}).then(function(data2) {
return load(data2)
}).then()複製程式碼
這裡沒有新增catch 捕獲錯誤 以至於在中間任何地方發生錯誤都查詢不到 很難排查
fn().then(function(data1) {
reuturn load(data1)
}).then(function(data2) {
return load(data2)
}).catch(err => console.log(err))複製程式碼
改成這樣有了catch 來捕獲錯誤在任何地方出現錯誤都會在這裡捕獲
Promise 鏈中可能出現錯誤一定新增 catch
- catch()與then(null, fn)
解釋下 即使有了catch 但是then return返回的是空的 這裡就捕獲到了 看下程式碼
fn().then(function(data1) {
reuturn load1()
}).catch(err => console.log(err))複製程式碼
catch捕獲的並不是fn的錯誤,而是load1的錯誤 所以這時候就要結合用了
fn().then(function(data1) {
reuturn load1()
}, err=>console.log(err))
.catch(err => console.log(err))複製程式碼
Promise 在有些情況下catch與then(null, fn)並不等同
- 處理併發時候 Promise.all 靜態方法
fn().then(promiseArr=> {
var resArr = [];
promiseArr.forEach(v=>{
v().then(res=> resArr.push(res))
})
return resArr;
}).then(ret => console.log(ret))複製程式碼
這樣寫感覺上是沒毛病的 但是有個問題 最後then 列印結果不能確保promiseArr 的Promise都能夠順利完成 所以這個時候 用Promise.all 靜態方法 在上一篇提到過這個靜態方法
這來回憶下
Promise.all(promises).then(function (posts) {
// ...
}).catch(function(reason){
// ...
});複製程式碼
- 這裡如果全部成功,狀態變為resolved,返回值將組成一個陣列傳給回撥
- 只要有一個失敗,狀態就變為rejected,返回值將直接傳遞給回撥
- 返回值也是個Promise例項
所以演變下
fn().then(promiseArr=> {
//var resArr = [];
//promiseArr.forEach(v=>{
//v().then(res=> resArr.push(res))
//})
//return resArr;
return Promise.all(promiseArr);
}).then(ret => console.log(ret))複製程式碼
在長度未知情況下併發 使用Promise.all 來解決
所以說:
then方法中 永遠 return 或 throw
如果 promise 鏈中可能出現錯誤,一定新增 catch
永遠傳遞函式給 then 方法
不要把 promise 寫成巢狀
參考連結 :
深入理解Promise
es6入門 阮一峰