js----promise(一)
阿新 • • 發佈:2017-08-06
cti sta 異常 結果 關於 比較 什麽是 其他 包括 資料鏈接:http://liubin.org/promises-book/#what-is-promise
1.什麽是promise
promise 是抽象異步處理對象以及對其進行各種操作的組件。
2.表現的形式是什麽樣子的?
回調函數:getAsync("fileA.txt", function(error, result){ if(error){// 取得失敗時的處理 throw error; } // 取得成功時的處理 });
使用promise進行異步處理:var promise = getAsyncPromise("fileA.txt"); promise.then(function(result){ // 獲取文件內容成功時的處理 }).catch(function(error){ // 獲取文件內容失敗時的處理 });
與異步回調函數相比較:在使用promise進行一步處理的時候,我們必須按照接口規定的方法編寫處理代碼。也就是說,除promise對象規定的方法(這裏的 then 或 catch)以外的方法都是不可以使用的, 而不會像回調函數方式那樣可以自己自由的定義回調函數的參數,而必須嚴格遵守固定、統一的編程方式來編寫代碼。
3.如何使用?
目前大致有下面三種類型。
Constructor
Promise類似於 XMLHttpRequest,從構造函數 Promise 來創建一個新建新promise對象作為接口。
要想創建一個promise對象、可以使用new來調用Promise的構造器來進行實例化。
var promise = new Promise(function(resolve, reject) { // 異步處理 // 處理結束後、調用resolve 或 reject });
Instance Method
對通過new生成的promise對象為了設置其值在 resolve(成功) / reject(失敗)時調用的回調函數 可以使用promise.then() 實例方法。
promise.then(onFulfilled, onRejected)
resolve(成功)時
onFulfilled 會被調用
reject(失敗)時
onRejected 會被調用
onFulfilled、onRejected 兩個都為可選參數。
promise.then 成功和失敗時都可以使用。 另外在只想對異常進行處理時可以采用 promise.then(undefined, onRejected) 這種方式,只指定reject時的回調函數即可。 不過這種情況下 promise.catch(onRejected) 應該是個更好的選擇。
promise.catch(onRejected)
Static Method
像 Promise 這樣的全局對象還擁有一些靜態方法。
包括 Promise.all() 還有 Promise.resolve() 等在內,主要都是一些對Promise進行操作的輔助方法。
function asyncFunction() {
return new Promise(function (resolve, reject) {
setTimeout(function () {
resolve(‘Async Hello world‘);
}, 16);
});
}
asyncFunction().then(function (value) {
console.log(value); // => ‘Async Hello world‘
}).catch(function (error) {
console.log(error);
});
asyncFunction 這個函數會返回promise對象, 對於這個promise對象,我們調用它的 then 方法來設置resolve後的回調函數, catch 方法來設置發生錯誤時的回調函數。
該promise對象會在setTimeout之後的16ms時被resolve, 這時 then 的回調函數會被調用,並輸出 ‘Async Hello world‘ 。
4.promise的狀態
用new Promise 實例化的promise對象有以下三個狀態。
"has-resolution" - Fulfilled
resolve(成功)時。此時會調用 onFulfilled
"has-rejection" - Rejected
reject(失敗)時。此時會調用 onRejecte
"unresolved" - Pending
既不是resolve也不是reject的狀態。也就是promise對象剛被創建後的初始化狀態等
關於上面這三種狀態的讀法,其中 左側為在 ES6 Promises 規範中定義的術語, 而右側則是在 Promises/A+ 中描述狀態的術語
5.代碼編寫
function getURL(URL) { return new Promise(function (resolve, reject) { var req = new XMLHttpRequest(); req.open(‘GET‘, URL, true); req.onload = function () { if (req.status === 200) { resolve(req.responseText); } else { reject(new Error(req.statusText)); } }; req.onerror = function () { reject(new Error(req.statusText)); }; req.send(); }); } // 運行示例 var URL = "http://httpbin.org/get"; getURL(URL).then(function onFulfilled(value){ console.log(value); }).catch(function onRejected(error){ console.error(error); });
getURL 只有在通過XHR取得結果狀態為200時才會調用 resolve - 也就是只有數據取得成功時,而其他情況(取得失敗)時則會調用 reject 方法。
resolve(req.responseText) 在response的內容中加入了參數。 resolve方法的參數並沒有特別的規則,基本上把要傳給回調函數參數放進去就可以了。 ( then 方法可以接收到這個參數值)
6.promise.resolve
一般情況下我們都會使用 new Promise() 來創建promise對象,但是除此之外我們也可以使用其他方法。這裏使用promise.resolve
例如:
new Promise(function(resolve){ resolve(42); });
在這段代碼中的 resolve(42); 會讓這個promise對象立即進入確定(即resolved)狀態,並將 42 傳遞給後面then裏所指定的 onFulfilled 函數。
在使用Promise.resolve(value) 等方法的時候,如果promise對象立刻就能進入resolve狀態的話,那麽你是不是覺得 .then 裏面指定的方法就是同步調用的呢?
實際上, .then 中指定的方法調用是異步進行的。
var promise = new Promise(function (resolve){ console.log("inner promise"); // 1 resolve(42); }); promise.then(function(value){ console.log(value); // 3 }); console.log("outer promise"); // 2
由於JavaScript代碼會按照文件的從上到下的順序執行,所以最開始 <1> 會執行,然後是 resolve(42); 被執行。這時候 promise 對象的已經變為確定狀態,FulFilled被設置為了 42 。
下面的代碼 promise.then 註冊了 <3> 這個回調函數,這是本專欄的焦點問題。
由於 promise.then 執行的時候promise對象已經是確定狀態,從程序上說對回調函數進行同步調用也是行得通的。但是即使在調用 promise.then 註冊回調函數的時候promise對象已經是確定的狀態,Promise也會以異步的方式調用該回調函數,這是在Promise設計上的規定方針。
因此 <2> 會最先被調用,最後才會調用回調函數 <3> 。
由於Promise保證了每次調用都是以異步方式進行的,所以我們在實際編碼中不需要調用 setTimeout 來自己實現異步調用。
js----promise(一)