Promise 是異步編程的一種方案,簡單說就是一個容器,裏面保存着某個將來纔會結束的事件的編程
結果,Promise 是一個對象,從它,能夠獲取異步操做的消息。數組
Promise 對象有如下兩個特色。promise
(1)對象的狀態不受外界影響。Promise 對象表明一個異步操做,有是三種狀態。pendding異步
(進行中),fulfilled(已成功)和rejected(已失敗)。異步編程
(2)一旦狀態改變,就不會在變,任什麼時候候均可以獲得這個結果,Promise 對象的狀態改變函數
只有兩種可能: 從pending 變爲fulfilled 和pending 變爲rejected.若是改變已經發生 了,你在fetch
對Promise對象添加回調函數,也會當即獲得這個結果。this
Promise 有一些缺點,首先沒法取消Promise ,一旦新建它就會當即執行,中途沒法取消。spa
若是不設置回調函數,Promise內部拋出的錯誤,不會當即反應到外部。當處於pendingprototype
狀態時,沒法得子目前進展到哪個階段。
用法
Promise 對象是一個構造函數,用來生成Promise實例。
構造函數接受一個函數做爲參數,該函數的兩個參數分別是resolve 和reject。
resolve 函數的做用是,將Promise 對象的狀態從「未完成」變爲「成功」,在異步操做成功
的時候調用,並將異步操做的結果,做爲參數參數傳遞。
reject 函數的做用是,將Promise對象的狀態從「未完成」變爲「失敗」,在異步操做失敗
的時候調用,並將異步操做報出錯誤,做爲參數傳遞出去。
Promise 實例陳倉之後,能夠使用then 方法分別指定resolved狀態和rejected狀態回調函數。
例如:
promise.then(function(value){ // success },function(error){ // failure });
第一個回調函數是狀態變爲resolved時調用,
第二個回調函數是Promise對象的狀態變爲rejected時調用。
Promise對象的簡單例子。
funcion timeout(ms){ return new Promise((resolve,reject)=>{ setTimeout(resolve,ms,'done'); }); } timeout(100).then((value)=>{ console.log(value); })
Promise 創建後就會當即執行
let promise = new Promise(function(resolve,reject){ console.log('Promise'); resolve(); }); promise.then(function() { console.log('resolved.'); }); console.log('Hi'); // Promise // Hi! // resolved Promise.prototype.then()
Promise 實例具備then 方法,也就是說,then方式定義在原型對象Promise.prototype上的。
then 方法返回的是一個新的Promise實例。 第一個參數是resolved狀態的回調函數,
第二個參數是rejected狀態的回調函數。
Promise.prototype.catch()
Promise.prototype.catch 方法是.then(null,rejection)的別名,用於指定發生錯誤時的回調函數。
寫法一:
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); }) Promise.all()
Promise.all 方法用於將多個Promise 實例,包裝成一個新的Promise實例。
const p = Promise.all([p1,p2,p3]);
Promise.all 方法接受一個數組做爲參數,p1,p2,p3都是Promise實例,若是不是,就會
調用下面講到的Promise.resolve方法,將參數轉爲Promise實例。
Promise.race()
Promise.race 方法一樣是將多個Promise實例,包裝成一個新的Promise實例。
const p = Promise.race([p1,p2,p3]);
上面例子中,只要p1,p2,p3之中有一個實例率先改變狀態,p的狀態就跟着改變。
那麼率先改變的Promise實例的返回值,就傳給p的回調函數。
const p = Promise.race([ fatch('/resource-that-may-take-a-while'), new Promise(function(resolve,reject){ setTimeout(()=> reject(new Error('request timeout')),5000) }) ]); p.then(response => console.log(response)); p.catch(error => console.log(error));
上面代碼中,若是5秒內fetch 方法沒法返回結果,變量p的狀態就會變爲rejected,從而
觸發catch 方法指定的回調函數。
Promise.resolve()
將現有對象轉爲Promise對象。
Promise.resolve('foo') 等價於
new Promise(resolve =>resolve('foo'))
Promise.resolve 方法的參數很是四種狀況
1.參數一個Promise實例,將不作任何修改,原封不動地返回這個實例。
2.參數一個thenable 對象。
3.參數不是具備then方法的對象,或根本就不是對象。
4. 不帶任何參數。
Promise.reject();
Promise.reject(reason) 方法會返回一個新的Promise實例,該實例的狀態爲rejected
done()
Promise對象的回調鏈,無論以then方法或是catch 方法結尾,要是最後一個方法拋出
錯誤,都有可能沒法捕捉到。提供一個done方法,老是處於回調鏈的尾端,保證拋出
任何有可能出現的錯誤。
Promise.prototype.done = function (onFulfilled,onRejected){ this.then(onFulfilled,onRejected).catch(function(reason){ // 拋出一個全局錯誤 setTimeout(()=>{throw reason},0) }); }
應用加載圖片
const preloadImge = function(path){ return new Promise(function(resolve,reject){ const image = new Image(); image.onload = resolve; image.onerror = regect; image.src = path; }) };