2017-05-26 72 views
1

我有點困惑,應該如何處理我的情況中的承諾。如何處理鏈式承諾

這是我廠:

return { 
    getCategory: function(categoryId) { 
    var ref = firebase.database().ref().child('categories').child(categoryId); 
    var category = $firebaseObject(ref); 
    return category.$loaded().then(function() { 
     return category; 
    }); 
    }, 
    getEntry: function(categoryId, entryId) { 
    var ref = firebase.database().ref().child('entries').child(categoryId).child(entryId); 
    var entry = $firebaseObject(ref); 
    return entry.$loaded().then(function() { 
     return entry; 
    }); 
    } 
} 

在我廠我會盡量避免做這樣的:

var d = $q.defer(); 
if() { 
    d.resolve(); 
} 
return d.promise; 

由於加載了$()返回一個承諾本身。

這是我的控制器:

var categoryId = 'abc'; 
var entryId = 'def'; 
// so here i'm getting the category 
MyFactory.getCategory(categoryId) 
.then(function(category) { 
    if(category.$value === null) 
    { 
     $scope.error = 'The category does not exist'; 
    } 
    else if(new Date() > new Date(category.expireDate)) 
    { 
     $scope.error = 'The category has expired'; 
    } 
    else { 
     $scope.category = category; 
     // if no errors 
     return MyFactory.getEntry(category.$id, entryId); 
    } 
}) 
.then(function(entry) { 
    if(entry.$value === null) 
    { 
     $scope.error = 'No such entry'; 
    } 
    else { 
     $scope.entry = entry; 
    } 
}) 
.catch(function(error) { 
    console.error(error); 
}); 

我想達到的目標是先拿到類別,然後是否有一些錯誤或不,分別獲得該條目。數據來自Firebase數據庫。

這樣的工作,但是我真的不知道我應該如何處理的承諾,當我想要做下一個。然後和不把它們築巢一個在其他像這樣:

MyFactory.getCategory().then(function(category) { 
    if(no category errors) { 
     MyFactory.getEntry().then(function() { 
      // ... 
     }); 
    } 
}); 

現在我在控制檯(它的類型錯誤條目未定義)出現錯誤,例如類別過期或不存在。 我想我在控制器中做了錯誤的事情,但我並不確定,希望你能幫助我消除所有疑慮。

所以真正的問題是我應該如何處理這個正確,按預期工作? 謝謝。

回答

1

當出現錯誤時,您應該返回拒絕的承諾。

請看下面的例子:

MyFactory 
    .getCategory(categoryId) 
    .then(function (category) { 
     if (category.$value === null) { 
      return $q.reject('The category does not exist'); 
     } 
     if (new Date() > new Date(category.expireDate)) { 
      return $q.reject('The category has expired'); 
     } 
     $scope.category = category; 
     return MyFactory.getEntry(category.$id, entryId); 
    }) 
    .then(function (entry) { 
     if (entry.$value === null) { 
      return $q.reject('No such entry'); 
     } 
     $scope.entry = entry; 
    }) 
    .catch(function (error) { 
     $scope.error = error; 
    }); 

不要忘記注入$q到控制器。

編輯

我也建議您將「錯誤的邏輯」爲您服務,所以該控制器總是收到.catch(error => { ... }).then(data => { ... })數據或一個錯誤字符串。這將使你的控制器更清潔,如果你在不同的控制器中使用這些服務方法,那麼你也不必在那裏複製你的邏輯。

服務

return { 
    getCategory: function(categoryId) { 
     var ref = firebase.database().ref().child('categories').child(categoryId); 
     var category = $firebaseObject(ref); 
     return category.$loaded().then(function() { 
      if (category.$value === null) { 
       return $q.reject('The category does not exist'); 
      } 
      if (new Date() > new Date(category.expireDate)) { 
       return $q.reject('The category has expired'); 
      } 
      return category; 
     }); 
    }, 
    getEntry: function(categoryId, entryId) { 
     var ref = firebase.database().ref().child('entries').child(categoryId).child(entryId); 
     var entry = $firebaseObject(ref); 
     return entry.$loaded().then(function() { 
      if (entry.$value === null) { 
       return $q.reject('No such entry'); 
      } 
      return entry; 
     }); 
    } 
} 

控制器

MyFactory 
    .getCategory(categoryId) 
    .then(function (category) { 
     $scope.category = category; 
     return MyFactory.getEntry(category.$id, entryId); 
    }) 
    .then(function (entry) { 
     $scope.entry = entry; 
    }) 
    .catch(function (error) { 
     $scope.error = error; 
    }); 
+0

哦,天哪!這幫助了我很多。謝謝。 但又有點混亂。您正在服務中使用$ q.reject。哪個承諾實際上是拒絕?既然你不做$ q.defer()? –

+0

我很高興我可以幫助! '$ q.reject()'是一個創建和拒絕承諾的「捷徑」。這裏是官方文檔 - https://docs.angularjs.org/api/ng/service/$q#reject –