Promise 處理非同步問題
實際開發過程中經常會遇到非同步的問題,比如:
前端向後端發起請求request1,需要獲得資料data1,發起請求request2同時需要請求引數data1,需要獲得資料data2,然後緊接著需要利用data2進行某項計算。。。。理想狀態下,按思路程式碼一路執行下來,沒毛病
但是!ajax是一個非同步的操作,由於網路延遲,request2執行時很可能request1還沒有返回data1,於是獲取不到data1,request2失敗,SO,data2也獲取不到了。。。然後一路錯下去,當request1返回data1時,程式已經一路崩下去無可挽回了
看一個demo:
function test(resolve, reject){ let m = 22;; setTimeout(function(){ m +=100; if(m<111){ resolve(m) }else{ reject(111); } }, 2000); console.log("哈哈1"); } var p = new Promise(test); p.then(function(res){ console.log("成功:",res); }); p.catch(function(res){ console.log("失敗:",res); }) console.log("哈哈2"); // 結果: //—————————————————————————— // 哈哈1 // 哈哈2 // 失敗: 111
而一般方法是利用回撥函式來解決非同步問題,然而回調函式這個東西我就感覺思維有點不合正常人類邏輯咯,而且程式碼也比較繁瑣。於是乎,引入Promise是個十分不錯的選擇。顧名思義,Promise即 “承諾” 的意思,既然是承諾,一諾千金那肯定是必須要做的。所以Promise(test)的含義就是承諾在未來的某個時間肯定會執行函式f
而函式f需要有兩個引數:resolve 和 reject 。這兩個引數都是函式。非同步執行操作執行成功時呼叫resolve函式,失敗時呼叫reject函式。(這兩個函式是js引擎自帶的不用自己定義喲)。而裡面的引數,resolve的引數會傳遞給then的回撥函式,reject的引數會傳遞給catch的回撥函式然後對其進行進一步處理。
或許說到這裡還是沒有感覺Promise有什麼牛逼的地方,那麼,如果比我文章開頭還要複雜點的有多個非同步操作的問題呢?
// 0.5秒後返回input*input的計算結果: function multiply(input) { return new Promise(function (resolve, reject) { console.log('calculating ' + input + ' x ' + input + '...'); setTimeout(resolve, 500, input * input); }); } // 3秒後返回input+input的計算結果: function add(input) { return new Promise(function (resolve, reject) { console.log('calculating ' + input + ' + ' + input + '...'); setTimeout(resolve, 3000, input + input); }); } var p = new Promise(function (resolve, reject) { console.log('start new Promise...'); resolve(123); }); p.then(multiply) .then(add) .then(multiply) .then(add) .then(function (result) { console.log('Got value: ' + result); });
如上述例子,當多個非同步問題是可以採取 p.then().then()..........這樣的寫法,當一個then執行完且執行成功時才會執行下一個then,失敗則停止執行