最近在做批量打印並監控顯示打印進度的功能,用到了很多異步函數,很多異步函數嵌套在回調函數里面,層層嵌套,導致代碼可閱讀性與可維護性變得十分糟糕,而且由於都是異步執行的函數,無法知道什么時候能回調結束,無法保證程序能安全執行,為了能解決這個問題,避免"回調地獄",於是就需要用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(() => {···});
詳細參考:
阮一峰
