Promise 是異步編程的一種解決方案。javascript
Promise
對象兩個特色:對象的狀態不受外界影響。Promise
對象表明一個異步操做,有三種狀態:pending
(進行中)、fulfilled
(已成功)和rejected
(已失敗)。只有異步操做的結果,能夠決定當前是哪種狀態,任何其餘操做都沒法改變這個狀態。java
一旦狀態改變,就不會再變。稱爲 resolved[已定型]。
從pending變爲fulfilled 或者 從pending變爲rejectedes6
Promise
缺點:沒法取消 Promise ,一旦新建它就會當即執行,沒法中途取消。
若是不設置回調函數,Promise 內部拋出的錯誤,不會反應到外部。
當處於 pending 狀態時,沒法得知目前進展到哪個階段(剛剛開始仍是即將完成)。編程
//新建promise對象 兩個參數resolve, reject const promise = new Promise(function(resolve, reject) { if (/* 異步操做成功 */){ resolve(value); } else { reject(error); } }); promise .then( //promise的resolved回調函數 result => {console.log("resolved: ", result)}, //then的第一方法成功回調, err => console.log("rejected: ", err) //then的第二個失敗回調 (可選) 不推薦 更推薦在catch捕獲錯誤 .catch(error => {···}) //promise的resolved回調函數 .finally(() => {···}); //在執行`then`或`catch`後,都會執行`finally`回調
第一個參數是resolved
狀態的回調函數,
第二個參數(可選)是rejected
狀態的回調函數json
getJSON("/post/1.json").then( post => getJSON(post.commentURL) ).then( comments => console.log("resolved: ", comments), err => console.log("rejected: ", err) ); 第一個`then`方法指定的回調函數,返回的是另外一個`Promise`對象。 第二個`then`方法指定的回調函數,就會等待這個新的`Promise`對象狀態發生變化。若是變爲`resolved`,就調用第一個回調函數, 若是狀態變爲`rejected`,就調用第二個回調函數。
Promise.prototype.catch() 是.then(null, rejection)或.then(undefined, rejection)的別名。數組
指定reject的回調
。在執行resolve的回調(也就是上面then中的第一個參數)時,若是拋出異常了(代碼出錯了),那麼並不會報錯卡死js,而是會進到這個catch方法中
。基本寫法 // 寫法一 const promise = new Promise(function(resolve, reject) { try { throw new Error('test'); } catch(e) { reject(e); } }); promise.catch(function(error) { console.log(error); }); // 寫法二 const promise = new Promise(function(resolve, reject) { reject(new Error('test')); }); promise.catch(function(error) { console.log(error); });
(1)Promise內部報錯 則then的第二個函數和catch就近原則能捕獲到promise
const promise = new Promise((resolve, rejected) => { throw new Error('test'); }); //狀況一:既有第二個函數也有catch時 就近原則 promise.then(res => { }, err => { console.log('我比較近我能捕獲到',err); }).catch(err1 => { console.log(err1); }); 運行結果:我比較近我能捕獲到,test //狀況二:只有第二個函數或只有catch 那就是它能捕獲
(2) then
的第二個的函數捕獲不了then中的第一個函數拋出的錯誤
,然後續的.catch
能夠捕獲。服務器
Promise.resolve() .then(function success (res) { throw new Error('error') }, function fail1 (e) { console.error('fail1: ', e)~~~~ }) .catch(function fail2 (e) { console.error('fail2: ', e) }) 運行結果: fail2: Error: error at success (...) at ...
如服務器使用 Promise 處理請求,而後使用finally
方法關掉服務器app
server.listen(port) .then(result => {···}) .finally(server.stop);
全返回回來纔回調操做
// 生成一個Promise對象的數組 const promises = [2, 3, 5, 7, 11, 13].map(function (id) { return getJSON('/post/' + id + ".json"); }); Promise.all(promises).then(function (posts) { }).catch(function(reason){ });
若是子promise沒有報錯了 可是子promise沒有定義catch, 就會調用promise.all的catch。異步
只要有一個回來就回調操做
// 有一個圖片加載完就添加到頁面 function loadImg(src){ return new Promise((resolve,reject)=>{ let img=document.createElement('img'); img.src=src; img.onload=function(){ resolve(img); } img.onerror=function(err){ reject(err); } }) } function showImgs(img){ let p=document.createElement('p'); p.appendChild(img); document.body.appendChild(p) } Promise.race([ loadImg('http://www.baidu.com/1.png'), loadImg('http://www.baidu.com/567751/2.png'), loadImg('http://www.baidu.com/567751/3.png') ]).then(showImgs)
轉爲Promise對象
(1)參數是一個 Promise 實例 原封不動地返回這個實例
(2)不帶有任何參數 直接返回一個resolved
狀態的 Promise 對象
(3)參數是一個thenable
對象(即具備then
方法的對象)
Promise.resolve方法會將這個對象轉爲 Promise 對象,而後就當即執行thenable對象的then方法。
//`thenable`對象指的是具備`then`方法的對象 let thenable = { then: function(resolve, reject) { resolve(42); } }; let p1 = Promise.resolve(thenable); p1.then(function(value) { console.log(value); // 42 });
(4)參數不是具備then
方法的對象,或根本就不是對象
若是參數是一個原始值,或者是一個不具備then
方法的對象,則Promise.resolve
方法返回一個新的 Promise 對象,狀態爲resolved
。
const p = Promise.resolve('Hello'); p.then(function (s){ console.log(s) }); // Hello
轉爲Promise對象 且狀態是rejected
和Promise.resolve方法同樣,Promise.reject方法產生的Promise對象的狀態是rejected的。
const p = Promise.reject('出錯了'); // 等同於 const p = new Promise((resolve, reject) => reject('出錯了')) p.then(null, function (s) { console.log(s) }); // 出錯了
mark一下 僅供參考 歡迎更正補充 Thanks
參考資料:
阮一峯:https://es6.ruanyifeng.com/?search=String.raw&x=0&y=0#docs/promise#Promise-all
關於promise的十道題目:https://juejin.im/post/5a0406...
性感的Promise,擁抱ta而後扒光ta:https://juejin.im/post/5ab20c...
通俗易懂的Promise:https://juejin.im/post/5afe6d...