2017-05-26 75 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 –