舉例詳解JavaScript中Promise的使用
摘錄 – Parse JavaScript SDK現(xiàn)在提供了支持大多數(shù)異步方法的兼容jquery的Promises模式,那么這意味著什么呢,讀完下文你就了解了。
“Promises” 代表著在javascript程序里下一個(gè)偉大的范式,但是理解他們?yōu)槭裁慈绱藗ゴ蟛皇羌?jiǎn)單的事。它的核心就是一個(gè)promise代表一個(gè)任務(wù)結(jié)果,這個(gè)任務(wù)有可能完成有可能沒完成。Promise模式唯一需要的一個(gè)接口是調(diào)用then方法,它可以用來注冊(cè)當(dāng)promise完成或者失敗時(shí)調(diào)用的回調(diào)函數(shù),這在CommonJS Promises/A proposal.大體講到了。比如,我想保存一個(gè)Prase.Object對(duì)象,這是個(gè)異步操作,在舊的回調(diào)范式中,你的代碼可能這樣寫:
object.save({ key: value }, { success:function(object) { // the object was saved. }, error:function(object, error) { // saving the object failed. } }); 在新的Promise范式中,同樣的代碼你可以這樣寫: object.save({ key: value }).then( function(object) { // the object was saved. }, function(error) { // saving the object failed. });
沒有多大的區(qū)別?那么有啥大不了的地方呢?好吧,promises的真正強(qiáng)大之處在于多重的鏈接,當(dāng)調(diào)用promise.then(func)時(shí)返回一個(gè)新的promise,它不會(huì)執(zhí)行直到上一個(gè)完成。但是這里有一種特殊的情況,如果我的回調(diào)通過then返回一個(gè)新的promise,那么通過then返回的promise將不會(huì)執(zhí)行,直到回調(diào)執(zhí)行完成。詳細(xì)細(xì)節(jié)請(qǐng)參考 Promises/A+,這是個(gè)復(fù)雜的規(guī)則,通過例子我們能更清楚的認(rèn)識(shí)下.
假設(shè)你寫了段登陸的代碼,查找對(duì)象然后更新它。在舊的回調(diào)范式中,你可以使用金字塔式的代碼完成:
Parse.User.logIn("user","pass", { success:function(user) { query.find({ success:function(results) { results[0].save({ key: value }, { success:function(result) { // the object was saved. } }); } }); } });
這看起來已經(jīng)很可笑,更可笑的是甚至沒有任何錯(cuò)誤處理。但是promise鏈?zhǔn)降慕Y(jié)構(gòu),使代碼看起來更舒服了:
Parse.User.logIn("user","pass").then(function(user) { returnquery.find(); }).then(function(results) { returnresults[0].save({ key: value }); }).then(function(result) { // the object was saved. });
哇!好多啦!
錯(cuò)誤處理
上面的代碼簡(jiǎn)單期間沒有添加錯(cuò)誤處理,但是添加了后你會(huì)發(fā)現(xiàn)在舊的回調(diào)代碼中一團(tuán)糟:
Parse.User.logIn("user","pass", { success:function(user) { query.find({ success:function(results) { results[0].save({ key: value }, { success:function(result) { // the object was saved. }, error:function(result, error) { // An error occurred. } }); }, error:function(error) { // An error occurred. } }); }, error:function(user, error) { // An error occurred. } });
由于promises知道處理是否完成,它可以傳遞錯(cuò)誤,不執(zhí)行任何回調(diào)直到遇到錯(cuò)誤。比如,上面的代碼可以簡(jiǎn)寫為:
Parse.User.logIn("user","pass").then(function(user) { returnquery.find(); }).then(function(results) { returnresults[0].save({ key: value }); }).then(function(result) { // the object was saved. },function(error) { // there was some error. });
通常,開發(fā)者認(rèn)為一個(gè)異步的promise失敗等同于拋出一個(gè)異常。事實(shí)上,如果一個(gè)回調(diào)拋出一個(gè)錯(cuò)誤,promise將返回失敗信息。把錯(cuò)誤傳遞到下一個(gè)可用的錯(cuò)誤處理器等同于拋出一次異常直到捕獲處理。
jQuery, Backbone, 和 Parse
有很多實(shí)現(xiàn)了promises的庫供開發(fā)者可用。 像jQuery的 Deferred, 微軟的 WinJS.Promise, when.js, q, 和dojo.Deferred.
然而,有個(gè)有趣的地方需要了解。 你可以在這里讀到 long and fascinating jQuery pull request discussion, jQuery的實(shí)現(xiàn)沒有完全按照Promises/A的規(guī)則來,很多地方用了其他實(shí)現(xiàn)方式,實(shí)驗(yàn)時(shí),我發(fā)現(xiàn)只有一個(gè)地方不太一樣。如果一個(gè)錯(cuò)誤處理器返回一些其他的信息,而不單純返回一個(gè)promise,大多數(shù)實(shí)現(xiàn)會(huì)考慮處理這個(gè)錯(cuò)誤,不做錯(cuò)誤傳遞。然而,jquery不認(rèn)為在此處處理這個(gè)錯(cuò)誤,而是把它向前傳遞。雖然,來自不同系統(tǒng)的promise應(yīng)該能無縫的混合使用,但是你還是應(yīng)當(dāng)注意些。一個(gè)潛在的問題是會(huì)在錯(cuò)誤處理器中返回promises(替換原始數(shù)值),因?yàn)樗鼈儠?huì)被同等對(duì)待。
doFailingAsync().then(function() { // doFailingAsync doesn't succeed. },function(error) { // Try to handle the error. return"It's all good."; }).then(function(result) { // Non-jQuery implementations will reach this with result === "It's all good.". },function(error) { // jQuery will reach this with error === "It's all good.". });
在 Backbone 0.9.10最新版本中,異步方法現(xiàn)在返回一個(gè) jqXHR,這是jquery promise的一種類型。Parse JavaScript SDK的一個(gè)目標(biāo)是盡可能的和Backbone兼容,我們不能返回一個(gè)jqXHR,因?yàn)樗?Cloud Code上不能很好地工作,因此,我們不都添加一個(gè) Parse.Promise類,它遵照jQuery Deferred的標(biāo)準(zhǔn)。 Parse JavaScript SDK最新版本已經(jīng)更新了所有的異步方法來支持這些新的對(duì)象,舊的回調(diào)方法仍然可用。但是基于上面列出的例子,我相信你更喜歡新的方式。所以試試promises吧!
相關(guān)文章
Ajax responseText解析json數(shù)據(jù)案例詳解
這篇文章主要介紹了Ajax responseText解析json數(shù)據(jù)案例詳解,本篇文章通過簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-08-08javascript中call()、apply()的區(qū)別
這篇文章主要介紹了javascript中call()、apply()的區(qū)別,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-03-03JavaScript中二維數(shù)組的創(chuàng)建技巧
二維數(shù)組本質(zhì)上是以數(shù)組作為數(shù)組元素的數(shù)組,即"數(shù)組的數(shù)組",類型說明符 數(shù)組名[常量表達(dá)式][常量表達(dá)式]。二維數(shù)組又稱為矩陣,行列數(shù)相等的矩陣稱為方陣。對(duì)稱矩陣a[i][j] = a[j][i],對(duì)角矩陣:n階方陣主對(duì)角線外都是零元素2021-11-11設(shè)計(jì)模式中的facade外觀模式在JavaScript開發(fā)中的運(yùn)用
外觀模式通過引入一個(gè)外觀角色來簡(jiǎn)化客戶端與子系統(tǒng)之間的交互,為復(fù)雜的子系統(tǒng)調(diào)用提供一個(gè)統(tǒng)一的入口,降低子系統(tǒng)與客戶端的耦合,接下來就來看設(shè)計(jì)模式中的facade外觀模式在JavaScript開發(fā)中的運(yùn)用2016-05-05JavaScript中的Math.atan2()方法使用詳解
這篇文章主要介紹了JavaScript中的Math.atan2()方法使用詳解,是JS入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2015-06-06JavaScript window.document的屬性、方法和事件小結(jié)
document屬性作為window對(duì)象的一個(gè)子對(duì)象被創(chuàng)建,是用于訪問頁面中所有元素的對(duì)象,這里簡(jiǎn)單整理下,方便學(xué)習(xí)js的朋友2012-10-10