最近在做批量打印並監控顯示打印進度的功能,用到了很多異步函數,很多異步函數嵌套在回調函數里面,層層嵌套,導致代碼可閱讀性與可維護性變得十分糟糕,而且由於都是異步執行的函數,無法知道什么時候能回調結束,無法保證程序能安全執行,為了能解決這個問題,避免"回調地獄",於是就需要用Promise函數。
什么是Promise函數
1. 什么是Promise函數?
Promise是一個方案,用來解決多層回調嵌套的解決方案。它現在是ES6的原生對象。
2. Promise函數有什么作用?
可以把一個多層嵌套的同步、異步都有回調的方法,給拉直為一串.then()組成的調用鏈。
3. Promise函數能解決什么問題?
多層嵌套的回調方法中,如果同時存在同步、異步的方法,那么實際執行順序會混亂。不好調試不好維護。
Promise函數的使用
1.Promise.prototype.then()
Promise 實例具有
then
方法,也就是說,then
方法是定義在原型對象Promise.prototype
上的。它的作用是為 Promise 實例添加狀態改變時的回調函數。前面說過,then
方法的第一個參數是resolved
狀態的回調函數,第二個參數(可選)是rejected
狀態的回調函數。
var getJSON = function(url) { var promise = new Promise(function(resolve, reject){ $.get(url,function (result) { resolve(result); }) }); return promise; }; getJSON("/test/getData").then(function(json) { console.log('Contents: ' + JSON.stringify(json)); }, function(error) { console.error('出錯了', error); });
2.Promise.prototype.catch()
Promise.prototype.catch
方法是.then(null, rejection)
的別名,用於指定發生錯誤時的回調函數。
getJSON('/posts.json').then(function(posts) { // ... }).catch(function(error) { // 處理 getJSON 和 前一個回調函數運行時發生的錯誤 console.log('發生錯誤!', error); });
上面代碼中,
一般來說,不要在
getJSON
方法返回一個 Promise 對象,如果該對象狀態變為
resolved
,則會調用
then
方法指定的回調函數;如果異步操作拋出錯誤,狀態就會變為
rejected
,就會調用
catch
方法指定的回調函數,處理這個錯誤。另外,
then
方法指定的回調函數,如果運行中拋出錯誤,也會被
catch
方法捕獲。
then
方法里面定義 Reject 狀態的回調函數(即
then
的第二個參數),總是使用
catch
方法。
// bad promise .then(function(data) { // success }, function(err) { // error }); // good promise .then(function(data) { //cb // success }) .catch(function(err) { // error });
上面代碼中,第二種寫法要好於第一種寫法,理由是第二種寫法可以捕獲前面then
方法執行中的錯誤,也更接近同步的寫法(try/catch
)。因此,建議總是使用catch
方法,而不使用then
方法的第二個參數。
跟傳統的try/catch
代碼塊不同的是,如果沒有使用catch
方法指定錯誤處理的回調函數,Promise 對象拋出的錯誤不會傳遞到外層代碼,即不會有任何反應。
3.Promise.prototype.finally()
finally
方法用於指定不管 Promise 對象最后狀態如何,都會執行的操作。該方法是 ES2018 引入標准的。
promise .then(result => {···}) .catch(error => {···}) .finally(() => {···});
詳細參考:
阮一峰