今天在整理前段時間做過的項目,發現之前在集成web環信的時候遇到過一個奇怪的需求:需要終止一個正在進行等待返回的promise,或者阻止其調用resolve和reject。(具體為何會有這種需求我也不太記得了。。。 現在回頭看,一定會有其他的常規解決方案)。 不過本著對未知牛角尖的專研精神(最近有點 ...
今天在整理前段時間做過的項目,發現之前在集成web環信的時候遇到過一個奇怪的需求:
需要終止一個正在進行等待返回的promise,或者阻止其調用resolve和reject。(具體為何會有這種需求我也不太記得了。。。
現在回頭看,一定會有其他的常規解決方案)。
不過本著對未知牛角尖的專研精神(最近有點閑),在咨詢知乎大神,重讀阮大神的《es6入門》書中promise一章後,
找到了一個原生js的解決方案:Promise.race。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> </head> <body> <button onclick="getInterface()">發送請求</button> <button id="cancel">取消調用介面</button> <script type="text/javascript"> //Promise.race([a,b])參數為一個promise對象組成的數組, //此方法用來比較啊a和b哪一個promise先返回,Promise.race結果就返回這個先返回的promise參數 function getInterface() { var promise1 = new Promise(function(resolve, reject) {
//模擬ajax非同步請求 setTimeout(resolve, 3000, '介面返回成功!'); }); var promise2 = new Promise(function(resolve, reject) { document.querySelector('#cancel').addEventListener('click', function() { reject('取消等待介面!'); }); }); Promise.race([promise1, promise2]).then(function(value) { console.log(value); }).catch(function(value) { console.log(value); }); } </script> </body> </html>
上面的代碼點擊發送請求按鈕後,調用getIterface方法,
方法內創建並立即執行兩個promise函數:promise1和promise2。Promise.race方法立即開始監聽這兩個promise對象的狀態。
1. 如果3秒內用戶有任何操作,那麼promise1內的resolve方法被調用:此時“介面”返回成功,Promise.race不再監聽promise2的狀態,
直接返回介面的返回結果:'介面返回成功!'。
2. 如果3秒內用戶點擊取消調用介面按鈕 ,那麼promise2內的reject方法被調用,此時Promise.race不再監聽promise2(非同步介面)的返回狀態,
直接返回promise2的返回結果:'取消等待介面'。
這樣就可以模擬外部中斷promise返回結果了,比如 promise1是一個ajax請求,那麼就可以在返回前在Promise.race中abort()請求了。