js----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 來本身實現異步調用。
相關文章
相關標籤/搜索