摘要:回調函數是的一大特色官方的基本都是以會回調方式傳遞函數返回值。針對這種普遍問題,應勢而生基本用法創建做一些異步操作的事情,然后一切正常的構造器接受一個函數作為參數,它會傳遞給這個回調函數兩個變量和。
Promise 是什么?
Promise 對象用來進行延遲(deferred) 和 異步(asynchronous) 計算。
一個 Promise 處于以下三種狀態之一:
pending: 初始狀態, 非 fulfilled 或 rejected.
fulfilled: 成功的操作.
rejected: 失敗的操作.
Promise 接口表示為一個值的代理,這個值在promise創建時未必已知. 它允許你將 handlers 與一個異步 action 最終的成功或失敗狀態關聯起來. 這使得異步方法可以像同步方法那樣返回值: 異步方法返回一個在未來某個時刻擁有一個值的 promise 來替代最終返回值.
pending狀態的promise既可帶著一個值成為 fulfilled 狀態,也可帶著一個reason成為 rejected 狀態. 任意情況發生時, 通過promise的 then 方法所排列(queued up)的相應handlers 就會被調用. (當綁定相應的 handler 時,如果 promise 已經處于 fulfilled 或 rejected 狀態這個 handler 將會被調用, 所以在異步操作的完成和它的 handler 的綁定之間不存在競爭條件.)
因為 Promise.prototype.then 和 Promise.prototype.catch 方法返回 promises, 所以它們可以被鏈式調用—一種被稱為 composition 的操作.
Promise 為何出現?簡單的說,Promise 被當成 callback hell 的救命仙丹。
回調函數是JavaScript的一大特色! node.js官方的api基本都是以會回調方式傳遞函數返回值。習慣同步編程的對這種異步方式多少會產生水土不服,而且層層嵌套,不知不覺就建造起了一座高高的回調金字塔。針對這種普遍問題,Promise應勢而生!
Promise 基本用法創建 Promise
var promise = new Promise(function(resolve, reject) { // 做一些異步操作的事情,然后…… if (/* 一切正常 */) { resolve("Stuff worked!"); } else { reject(Error("It broke")); } });
Promise 的構造器接受一個函數作為參數,它會傳遞給這個回調函數兩個變量 resolve 和 reject。在回調函數中做一些異步操作,成功之后調用 resolve,否則調用 reject。
調用 reject 的時候傳遞給它一個 Error 對象只是個慣例并非必須,這和經典 JavaScript 中的 throw 一樣。傳遞 Error 對象的好處是它包含了調用堆棧,在調試的時候會有點用處。
使用 Promise:
promise.then(function(result) { console.log(result); // “完美!” }, function(err) { console.log(err); // Error: "出問題了" });
“then”接受兩個參數,成功的時候調用一個,失敗的時候調用另一個,兩個都是可選的,所以你可以只處理成功的情況或者失敗的情況。
Promise 實踐值的處理
你可以對結果做些修改然后返回一個新值:
var promise = new Promise(function(resolve, reject) { resolve(1); }); promise.then(function(val) { console.log(val); // 1 return val + 2; }).then(function(val) { console.log(val); // 3 });
隊列的異步操作
你也可以把“then”串聯起來依次執行異步操作。
當你從“then”的回調函數返回的時候,這里有點小魔法。如果你返回一個值,它就會被傳給下一個“then”的回調;而如果你返回一個“類 Promise”的對象,則下一個“then”就會等待這個 Promise 明確結束(成功/失敗)才會執行。例如:
你也可以把“then”串聯起來依次執行異步操作。
當你從“then”的回調函數返回的時候,這里有點小魔法。如果你返回一個值,它就會被傳給下一個“then”的回調;而如果你返回一個“類 Promise”的對象,則下一個“then”就會等待這個 Promise 明確結束(成功/失敗)才會執行。例如:
返回一個值
getJSON("story.json").then(function(story) { return getJSON(story.chapterUrls[0]); }).then(function(chapter1) { console.log("Got chapter 1!", chapter1); });
你返回一個“類 Promise”的對象
var storyPromise; function getChapter(i) { storyPromise = storyPromise || getJSON("story.json"); return storyPromise.then(function(story) { return getJSON(story.chapterUrls[i]); }) } // 用起來非常簡單: getChapter(0).then(function(chapter) { console.log(chapter); return getChapter(1); }).then(function(chapter) { console.log(chapter); });
錯誤處理
前面已經看到,“then”接受兩個參數,一個處理成功,一個處理失敗(或者說肯定和否定,按 Promise 術語):
get("story.json").then(function(response) { console.log("Success!", response); }, function(error) { console.log("Failed!", error); });
你還可以使用“catch”:
get("story.json").then(function(response) { console.log("Success!", response); }).catch(function(error) { console.log("Failed!", error); });
Promise 被否定之后會跳轉到之后第一個配置了否定回調的 then(或 catch,一樣的)。對于 then(func1, func2) 來說,必會調用 func1 或 func2 之一,但絕不會兩個都調用。而 then(func1).catch(func2) 這樣,如果 func1 返回否定的話 func2 也會被調用,因為他們是鏈式調用中獨立的兩個步驟。看下面這段代碼:
asyncThing1().then(function() { return asyncThing2(); }).then(function() { return asyncThing3(); }).catch(function(err) { return asyncRecovery1(); }).then(function() { return asyncThing4(); }, function(err) { return asyncRecovery2(); }).catch(function(err) { console.log("Don"t worry about it"); }).then(function() { console.log("All done!"); });Promise API 參考
靜態方法
Promise.resolve(promise);
返回一個 Promise(當且僅當 promise.constructor == Promise)
Promise.resolve(thenable);
從 thenable 對象創建一個新的 Promise。一個 thenable(類 Promise)對象是一個帶有“then”方法的對象。
Promise.resolve(obj);
創建一個以 obj 為肯定結果的 Promise。
Promise.reject(obj);
創建一個以 obj 為否定結果的 Promise。為了一致性和調試便利(如堆棧追蹤),obj 應該是一個 Error 實例對象。
Promise.all(array);
創建一個 Promise,當且僅當傳入數組中的所有 Promise 都肯定之后才肯定,如果遇到數組中的任何一個 Promise 以否定結束,則拋出否定結果。每個數組元素都會首先經過 Promise.resolve,所以數組可以包含類 Promise 對象或者其他對象。肯定結果是一個數組,包含傳入數組中每個 Promise 的肯定結果(且保持順序);否定結果是傳入數組中第一個遇到的否定結果。
Promise.race(array);
創建一個 Promise,當數組中的任意對象肯定時將其結果作為肯定結束,或者當數組中任意對象否定時將其結果作為否定結束。
其實已經有一些第三方庫實現了 Promise 的功能:
Q
when
WinJS
RSVP.js
上面這些庫和 JavaScript 原生 Promise 都遵守一個通用的、標準化的規范:Promises/A+,jQuery 有個類似的方法叫 Deferred,但不兼容 Promises/A+ 規范,于是會有點小問題,使用需謹慎。jQuery 還有一個 Promise 類型,它其實是 Deferred 的縮減版,所以也有同樣問題。
目前的瀏覽器已經(部分)實現了 Promise。
Chrome 32、Opera 19 和 Firefox 29 以上的版本已經默認支持 Promise。由于是在 WebKit 內核中所以我們有理由期待下個版本的 Safari 也會支持,并且 IE 也在不斷的開發中。
要在這兩個瀏覽器上達到兼容標準 Promise,或者在其他瀏覽器以及 Node.js 中使用 Promise,可以看看這個 polyfill(gzip 之后 2K)。
相關參考http://www.html5rocks.com/zh/tutorials/es6/promises/
http://www.w3ctech.com/topic/721
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise
http://www.codemud.net/~thinker/GinGin_CGI.py/show_id_doc/488
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/92321.html
摘要:前端日報精選理解的專題之偏函數譯理解事件驅動機制游戲開發前端面試中的常見的算法問題發布中文前端頁面傳參尚妝產品技術刊讀基礎系列二之實現大轉盤抽獎掘金指南眾成翻譯編程插入排序眾成翻譯源碼講解函數技術風暴初體驗個人文 2017-08-16 前端日報 精選 理解 JavaScript 的 async/awaitJavaScript專題之偏函數[譯]理解 Node.js 事件驅動機制Pokem...
摘要:去年年初寫了一個擴展十閱后,一直想寫個十閱出來,奈何懶癌后期,一直拖到最近才完成原型。這次心血來潮閑的蛋疼,想起去年年初就有所耳聞的,于是就打算用它來耍耍。使用鏈接庫在設備上運行用來斷點調試地址學習資源圖圖圖 去年年初寫了一個 chrome 擴展「十閱」后,一直想寫個十閱 app 出來,奈何懶癌后期,一直拖到最近才完成原型。 其實很早之前就已經寫過一個 hybrid app 了,使用了...
摘要:但在后端代碼中容易識別成注釋,慎用忘記加分號啦執行為協議,這里意思為不執行任何命令忘記加分號啦執行為協議,這里意思為不執行任何命令標簽也用于跳轉頁面,但必須有按鈕或者點擊才能跳轉完整樣式網址同標簽提交必須寫屬性才能被提交。 碎碎念 關于布局 css布局:橫向、縱向 2019年新進展:css grid git bash 上安裝 http server 目的在于不使用 file:/...
閱讀 1815·2023-04-26 01:55
閱讀 1078·2021-09-30 09:47
閱讀 1673·2019-08-30 15:54
閱讀 740·2019-08-30 15:53
閱讀 692·2019-08-30 15:52
閱讀 1133·2019-08-30 15:44
閱讀 2409·2019-08-30 14:06
閱讀 1057·2019-08-29 16:39