標籤:
非同步模式在Web編程中變得越來越重要,對於Web主流語言JavaScript來說,這種模式實現起來不是很利索,為此,許多 JavaScript庫(比如 jQuery和Dojo、AngularJS)添加了一種稱為Promise的抽象(術語稱作Deferred模式)。通過這些庫,開發人員能夠在實際編 程中使用Promise模式,每個Promise都擁有一個叫做then的唯一介面,當Promise失敗或成功時,它就會進行回調。它代表了一種可能會 長時間運行而且不一定必須完成的操作結果。這種模式不會阻塞和等待長時間的操作完成,而是返回一個代表了承諾的(promised)結果的對象。
本文我們將討論JavaScript庫(比如jQuery、AngularJS)是如何使用Promise模式的來處理非同步,其實就是通過回調的方式提供容錯支援。
下面讓我們來看看jQuery是如何操作的:
[js] view plaincopy
- var $info = $("#info");
- $.ajax({
- url:"/echo/json/",
- data: { json: JSON.stringify({"name": "someValue"}) },
- type:"POST",
- success: function(response)
- {
- $info.text(response.name);
- }
- });
在 這個例子中,你可以看到當設定成功後會指定一個回調,這並不是Promise,但卻是一種很好的回調方式。當Ajax調用完成後,它便會執行 success函數。根據庫所使用的非同步作業,你可以使用各種不同的回調(即任務是否成功,都會進行回調,做出響應)。使用Promise模式會簡化這個 過程,非同步作業只需返回一個對象調用。這個Promise允許你調用一個叫做then的方法,然後讓你指定回調的function(s)個數,下面讓我們 來看看jQuery是如何建立Promise的:
[js] view plaincopy
- var $info = $("#info");
- $.ajax({
- url: "/echo/json/",
- data: {
- json: JSON.stringify({
- "name": "someValue"
- })
- },
- type: "POST"
- })
- .then(function (response) {
- $info.text(response.name);
- });
有趣的是,ajax對象返回xhr對象實現Promise模式,所以我們可以調用then方法,這樣做的優勢是你可以鏈式調用,實現獨立操作,如下所示 :
[js] view plaincopy
- var $info = $("#info");
- $.ajax({
- url: "/echo/json/",
- data: {
- json: JSON.stringify({
- "name": "someValue"
- })
- },
- type: "POST"
- })
- .then(function (response) {
- $info.text(response.name);
- })
- .then(function () {
- $info.append("...More");
- })
- .done(function () {
- $info.append("...finally!");
- });
由於許多庫都開始採用Promise模式,所以非同步作業會變的非常容易。但如果站在相反的角度思考,Promise將會是什麼樣子的呢?其中一個非常重要的模式是函數可以接受兩種功能,一個是成功時的回調,另一個是失敗時的回調。
[js] view plaincopy
- var $info = $("#info");
- $.ajax({
- // Change URL to see error happen
- url: "/echo/json/",
- data: {
- json: JSON.stringify({
- "name": "someValue"
- })
- },
- type: "POST"
- })
- .then(function (response) {
- // success
- $info.text(response.name);
- },
- function () {
- // failure
- $info.text("bad things happen to good developers");
- })
- .always(function () {
- $info.append("...finally");
- });
需要注意的是,在jQuery裡,無論成功還是失敗,我們都會使用一個調用來指定我們想要調用的。下面讓來看看AngularJS是如何使用Promise模式的:
[js] view plaincopy
- var m = angular.module("myApp", []);
- m.factory("dataService", function ($q) {
- function _callMe() {
- var d = $q.defer();
- setTimeout(function () {
- d.resolve();
- //defer.reject();
- }, 100);
- return d.promise;
- }
- return {
- callMe: _callMe
- };
- });
- function myCtrl($scope, dataService) {
- $scope.name = "None";
- $scope.isBusy = true;
- dataService.callMe()
- .then(function () {
- // Successful
- $scope.name = "success";
- },
- function () {
- // failure
- $scope.name = "failure";
- })
- .then(function () {
- // Like a Finally Clause
- $scope.isBusy = false;
- });
- }
你可以在JSFiddle裡試試這些例子,並且看看會產生哪些效果。使用Promise來操作非同步是一種非常簡單的方式,而且還可以簡化你的代碼,豈不是一舉兩得的好方法。
更多關於Promise的介紹及樣本,可以前往官網查看。
來自:JavaScript Promise
本文為CSDN編譯整理,未經允許不得轉載,如需轉載請聯絡market#csdn.net(#換成@)
JavaScript非同步編程助手:Promise模式 【轉】