舉例詳解JavaScript中Promise的使用
摘錄 – Parse JavaScript SDK現(xiàn)在提供了支持大多數(shù)異步方法的兼容jquery的Promises模式,那么這意味著什么呢,讀完下文你就了解了。
“Promises” 代表著在javascript程序里下一個偉大的范式,但是理解他們?yōu)槭裁慈绱藗ゴ蟛皇羌唵蔚氖?。它的核心就是一個promise代表一個任務(wù)結(jié)果,這個任務(wù)有可能完成有可能沒完成。Promise模式唯一需要的一個接口是調(diào)用then方法,它可以用來注冊當promise完成或者失敗時調(diào)用的回調(diào)函數(shù),這在CommonJS Promises/A proposal.大體講到了。比如,我想保存一個Prase.Object對象,這是個異步操作,在舊的回調(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的真正強大之處在于多重的鏈接,當調(diào)用promise.then(func)時返回一個新的promise,它不會執(zhí)行直到上一個完成。但是這里有一種特殊的情況,如果我的回調(diào)通過then返回一個新的promise,那么通過then返回的promise將不會執(zhí)行,直到回調(diào)執(zhí)行完成。詳細細節(jié)請參考 Promises/A+,這是個復(fù)雜的規(guī)則,通過例子我們能更清楚的認識下.
假設(shè)你寫了段登陸的代碼,查找對象然后更新它。在舊的回調(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)很可笑,更可笑的是甚至沒有任何錯誤處理。但是promise鏈式的結(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.
});
哇!好多啦!
錯誤處理
上面的代碼簡單期間沒有添加錯誤處理,但是添加了后你會發(fā)現(xiàn)在舊的回調(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.
},
error:function(result, error) {
// An error occurred.
}
});
},
error:function(error) {
// An error occurred.
}
});
},
error:function(user, error) {
// An error occurred.
}
});
由于promises知道處理是否完成,它可以傳遞錯誤,不執(zhí)行任何回調(diào)直到遇到錯誤。比如,上面的代碼可以簡寫為:
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ā)者認為一個異步的promise失敗等同于拋出一個異常。事實上,如果一個回調(diào)拋出一個錯誤,promise將返回失敗信息。把錯誤傳遞到下一個可用的錯誤處理器等同于拋出一次異常直到捕獲處理。
jQuery, Backbone, 和 Parse
有很多實現(xiàn)了promises的庫供開發(fā)者可用。 像jQuery的 Deferred, 微軟的 WinJS.Promise, when.js, q, 和dojo.Deferred.
然而,有個有趣的地方需要了解。 你可以在這里讀到 long and fascinating jQuery pull request discussion, jQuery的實現(xiàn)沒有完全按照Promises/A的規(guī)則來,很多地方用了其他實現(xiàn)方式,實驗時,我發(fā)現(xiàn)只有一個地方不太一樣。如果一個錯誤處理器返回一些其他的信息,而不單純返回一個promise,大多數(shù)實現(xiàn)會考慮處理這個錯誤,不做錯誤傳遞。然而,jquery不認為在此處處理這個錯誤,而是把它向前傳遞。雖然,來自不同系統(tǒng)的promise應(yīng)該能無縫的混合使用,但是你還是應(yīng)當注意些。一個潛在的問題是會在錯誤處理器中返回promises(替換原始數(shù)值),因為它們會被同等對待。
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)在返回一個 jqXHR,這是jquery promise的一種類型。Parse JavaScript SDK的一個目標是盡可能的和Backbone兼容,我們不能返回一個jqXHR,因為它在 Cloud Code上不能很好地工作,因此,我們不都添加一個 Parse.Promise類,它遵照jQuery Deferred的標準。 Parse JavaScript SDK最新版本已經(jīng)更新了所有的異步方法來支持這些新的對象,舊的回調(diào)方法仍然可用。但是基于上面列出的例子,我相信你更喜歡新的方式。所以試試promises吧!
相關(guān)文章
getElementById在任意一款瀏覽器中都可以用嗎的疑問回復(fù)
getElementById在任意一款瀏覽器中都可以用嗎的疑問回復(fù)...2007-05-05
Javascript學習筆記之 函數(shù)篇(三) : 閉包和引用
本系列好久沒更新了,今天重新拿過來,繼續(xù)前面未完成的事項,本文我們就來談?wù)凧avascript 中一個最重要的特性--閉包的使用引用。2014-11-11
JavaScript基礎(chǔ)語法、dom操作樹及document對象
本文介紹了學習javascript重要的3個內(nèi)容基礎(chǔ)語法、dom操作樹及document對象,小伙伴們一定要弄明白才行2014-12-12
actionscript與javascript的區(qū)別
actionscript是flash的腳本語言,目前已經(jīng)由adobe公司升級到3.0版本,成為了真正意義的oop語言,JavaScript是由netscape工程師設(shè)計完成的一門腳本語言,用于web開發(fā)的前端腳本2011-05-05
JavaScript中Function()函數(shù)的使用教程
這篇文章主要介紹了JavaScipt中Function()函數(shù)的使用教程,是JavaScipt入門學習中的基礎(chǔ)知識,需要的朋友可以參考下2015-06-06

