Promises in AngularJS, Explained as a Cartoon(翻譯)

有天早上,爸爸跟兒子:「兒子啊,去預測天氣看看!」

每個星期天早上,爸爸都會叫兒子帶著他的超強望遠鏡到較高的山丘上去預測下午天氣如何。兒子答應(promise)爸爸他會去預測天氣。他在離開門前創造了一個 承諾(promise)。

此時,爸爸決定若是好天氣,明天將準備去釣個魚。若是壞天氣則不去。還有,若兒子沒有預測天氣的話,他們也將留在家裡。

大約三十分鐘左右後,兒子回來了。每周每周都發生著不一樣的結果:

結果A) 成功預測天氣!是晴天 :-)

兒子成功的預測天氣,是晴朗的天氣且太陽很大! 承諾被實現了(兒子遵守承諾)然後爸爸決定打包行李準備星期天去釣魚。

結果B) 成功預測天氣!多雲且雨天 :-(

兒子成功的預測天氣,但似乎是多雲且有雨的天氣承諾被實現了但由於壞天氣爸爸決定待在家裡。

結果C) 沒能預測天氣 :-/

有問題造成兒子預測天氣失敗; 由於太霧導致看不到將會是甚麼天氣。兒子在離開時所做的承諾無法達成 - 承諾被拒絕! 爸爸決定待在家裡,不值得出門冒險。


這在程式碼裡長怎麼樣?

爸爸在控制(controll)這個情況的邏輯,然後他處理他兒子猶如在處理一個服務(Service)。

我們已經陳述這個邏輯,爸爸要求兒子去預測天氣,當兒子沒辦法立刻告訴他結果時,爸爸將會在等待時去做其他事,所以兒子答應(promise)他將會回報天氣為何。若爸爸得到天氣預報,他不是打包行李準備釣魚去,就是待在家裡。重點在這,兒子爬上山丘這件事並不會’阻撓‘爸爸做任何事,所以這就是為什麼創造承諾(promise)很棒,承諾可在之後被解決(實現或拒絕)。

利用Angular的then function,我們可以指定爸爸對於每個結果做甚麼事。then function 可以接受兩個參數: 一個是在承諾實現時執行,另一個則是在承諾被拒絕時執行。

Controller: FatherCtrl

爸爸控制情況在這:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// function somewhere in father-controller.js
var makePromiseWithSon = function() {
// This service's function returns a promise, but we'll deal with that shortly
SonService.getWeather()
// then() called when son gets back
.then(function(data) {
// promise fulfilled
if (data.forecast==='good') {
prepareFishingTrip();
} else {
prepareSundayRoastDinner();
}
}, function(error) {
// promise rejected, could log the error with: console.log('error', error);
prepareSundayRoastDinner();
});
};

Service: SonService

兒子被當成一個服務(Service),爬上山丘及試著預測天氣。當兒子利用望遠鏡來查看最接近的天氣時,我們假設他是透過類似天氣API,也就是說是非同步的動作,他將會得到一個變數答案,也有可能是個問題(例如,500 response,霧天)。

從 Fishing Weather API 得到的 response 將會回傳給承諾(promise),若有實現。他將會是這個格式: {“forecast”: “good”}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
app.factory('SonService', function ($http, $q) {
return {
getWeather: function() {
// the $http API is based on the deferred/promise APIs exposed by the $q service
// so it returns a promise for us by default
return $http.get('http://fishing-weather-api.com/sunday/afternoon')
.then(function(response) {
if (typeof response.data === 'object') {
return response.data;
} else {
// invalid response
return $q.reject(response.data);
}
}, function(response) {
// something went wrong
return $q.reject(response.data);
});
}
};
});

總結

這個比喻展示了爸爸對兒子做出一個關於天氣預測的非同步要求。在兒子離開後爸爸不會在門旁等待答案,因為他還有其他事要做。反而,他在門前做了一個承諾(promise),並且對三種不同的情況做出三種不同的結果(好天氣/壞天氣/沒預測)。兒子在離開時馬上做出承諾,並且在他回來時會解決拒絕

兒子正在處理一個非同步的服務(利用望遠鏡查看天空/利用天氣API)來取得資料,但老人家肯定不懂這些新科技。

原文: http://andyshora.com/promises-angularjs-explained-as-cartoon.html