異步編程之promise
是ES6中新增的異步編程解決方案。
1.構造函數。
可以通過promise構造函數來實例化。
數據:
const imgs = [ ‘https://img.alicdn.com/tps/i4/TB1fD77gfuSBuNkHFqDSutfhVXa.jpg_240x240q90.jpg‘, ‘https://img.alicdn.com/simba/img/TB1CYyRdAUmBKNjSZFOSuub2XXa.jpg‘, ‘https://img.alicdn.com/imgextra/i3/31/TB2Yxd3gsuYBuNkSmRyXXcA3pXa_!!31-0-lubanu.jpg_200x200q90.jpg‘ ]
實例化Promise對象接收一個參數是回調函數,這個函數又有兩個參數,分別是resolve和reject。
resolve異步操作執行成功的回調函數。reject異步操作執行失敗的回調函數。
const p = new Promise(function(resolve, reject) { const img = new Image(); img.src = imgs[0]; img.onload = function() { resolve(this); }; img.onerror = function(err) { reject(err); } });
Promise對象有三種狀態:狀態完全由異步操作的結果來決定。狀態一旦改變之後就不會再改變。
pending(進行中)===>Resolved(已完成)
pending(進行中)===>Rejected(已失敗)
這就創建了promise對象了,但是並沒有任何效果。這時就需要用到promise原型上的方法:Promise.prototype.then(), Promise.prototype.catch (),用來處理異步操作結果。處理成功和捕獲異常。
2.兩個原型方法。Promise.prototype.then(), Promise.prototype.catch ()
const p = new Promise(function(resolve, reject) { const img = new Image(); img.src = ‘ ‘; img.onload = function() { resolve(this); }; img.onerror = function() { reject(new Error(‘圖片加載失敗‘)); } }); p.then(function(img) { document.body.appendChild(img); }).catch(function(err) { console.log(err); })
3.兩個常用的靜態方法。Promise.all(), Promise.resolve()
3.1 promise.all()
可以將多個promise實例封裝成一個新的promise實例。使用的時候接受一個數組,這個數組就是多個promise組成的集合。除了接受數組,還可以接收具有itertor接口的對象。
當所有promise實例的狀態都變為resolved,promise.all的狀態才會變成resolved,此時返回值組成一個數組,傳遞給then中的resolve函數。只要有一個被rejected,promised.all的狀態就變成rejected,此時第一個被rejected的實例的返回值,會傳遞給p的回調函數。
function loadImg(url) { const p = new Promise(function(resolve, reject) { const img = new Image(); img.src = url; img.onload = function() { resolve(this); }; img.onerror = function() { reject(new Error(‘圖片加載失敗‘)); } }); return p; } const allDone = Promise.all([loadImg(imgs[0]), loadImg(imgs[1]), loadImg(imgs[2])]); allDone.then(function(datas) { datas.forEach(function(item, i) { document.body.appendChild(item); }) }).catch(function(err) { console.log(err); })
三張圖片全部在頁面顯示。如果換成:
const allDone = Promise.all([loadImg(imgs[0]), loadImg(imgs[1]), loadImg(imgs[2]), loadImg(‘ ‘)]);
一張都加載不出來,並且控制臺打印出錯信息。
3.2 Promise.resolve()
將一個對象轉換為promise對象。
用法1:接收一個promise實例,返回promise實例,不做任何修改。
Promise.resolve(loadImg(imgs[0])).then(function(img){ document.body.appendChild(img); })
用法2:將對象轉為promise對象,然後就立即執行thenable對象的then方法。
用法3:參數是一個基本數據類型或者不傳參數,那麽返回一個狀態為resolved即成功的promise對象。Promise.resolve(‘perihe‘).then(function(str) { console.log(str); //perihe })
不傳參:
const p = Promise.resolve() console.log(p);
狀態為resolved的promised對象:
異步編程之promise