2015-02-06 63 views
0

我在寫一個將被異步執行的函數。突然間,我的腦海裏浮現出一個問題。AngularJS延遲對象的行爲

比方說,我有以下更新學生記錄的功能。

module.factory('StudentService', function($http, $q) { 
    var service = {}; 

    service.updateStudent = function(studentData) { 
     var deferred = $q.defer(); 

     $http.put('http://www.example.com/student/update', studentData, { 
      headers: { 'Content-Type': 'application/json' } 
     }).success(function(response) { 
      if (response.success) { 
       deferred.resolve(response.data); 
      } else { 
       // I am not resolving the deferred object here 
      } 
     }).error(function(response) { 
      // I am not rejecting the deferred object here 
     }); 

     return deferred.promise; 
    }; 

    return service; 
}); 

我想問一下,

  1. 會發生什麼遞延對象,如果問題沒有解決或拒絕?
  2. 如果延遲對象沒有解決或拒絕,它會導致錯誤鏈像StudentService.updateStudent(data).then(...)
  3. 既沒有解決也沒有拒絕延遲對象的實際用法?

回答

2
  1. 如果延遲未解決或拒絕,則相應的處理程序將永遠不會被調用。
  2. 沒有錯誤 - 只是不會調用鏈中的連續處理程序。
  3. 過於廣泛,SO

題外話:

你不需要當您使用已返回一個承諾函數使用$q.defer(如$http) - 這就是所謂的deferred anti-pattern 。只需return原始承諾(或與.then創建的承諾)。

+0

題外話是非常有用的。 – 2015-02-06 08:27:37

1

既沒有解決也沒有拒絕延遲對象的實際用法?

是的,確保從不調用鏈接.then().catch()的任何回調。

因此,有三種可能的結果:

  • 承諾變爲「解決」:承諾如下鏈的成功路徑。
  • 承諾成爲「拒絕」:承諾鏈遵循故障路徑。
  • 承諾仍然「未決」:沒有任何下游發生,但仍然可以如果(引用)承諾仍然存在,它會變成解決或拒絕。

也就是說,這是一個不好的做法,掛起承諾。你應該盡力解決或拒絕。

題外話,但相關...

像任何JS對象,承諾將被垃圾收集時,有沒有參考它。但是,由於承諾的性質,刪除所有引用通常非常困難 - 它們並不總是以詞彙形式表示(在應用程序代碼中)。例如,即使在沒有明確的任務分配的情況下,承諾的「隱藏」引用也潛伏在每個承諾鏈中。每一個承諾,無論是詞法表徵與否,都會佔據記憶。

回到主題...

永遠不會解決一個承諾,應該:

  • 無法創建(並不總是可能)
  • 被刪除(很少簡單)

就我個人而言,我覺得在這方面需要做更多的工作。