在angular代码中,我有一个像这样的链式承诺:
// a function in LoaderService module.
var ensureTypesLoaded= function(){
return loadContainerTypes($scope).then(loadSampleTypes($scope)).then(loadProjectList($scope)).then(loadSubjectTypes($scope));
}
这些函数都返回一个promise,它从资源中加载东西,并在错误和成功时额外修改$scope,例如:
var loadProjectList = function ($scope) {
// getAll calls inside a resource method and returns promise.
return ProjectService.getAll().then(
function (items) {
// succesfull load
console.log("Promise 1 resolved");
$scope.projectList = items;
}, function () {
// Error happened
CommonService.setStatus($scope, 'Error!');
});
};
我打算在控制器初始化的代码中使用in:
// Part of page's controller initialization code
LoaderService.ensureTypesLoaded($scope).then(function () {
// do something to scope when successes
console.log("I will do something here after all promises resolve");
}, function () {
// do something when error
});
然而,这并不像我想的那样工作。理想情况下,"在所有承诺解决后,我会在这里做一些事情"必须在所有承诺解决后出现。相反,我可以看到它出现在ensureTypesLoaded中列出的函数中已解决的承诺的消息之前。
我想创建一个函数ensureTypesLoaded,这样:
- 它返回一个承诺,当所有的链式加载都解决了;
- 如果任何"内部"承诺失败,函数不应该继续下一个调用,而是返回被拒绝的承诺。
- 显然,如果我调用ensureTypesLoaded().then(…),那么then()中的东西必须在ensureTypesLoaded内部的所有内容都被解析后被调用。
请帮助我正确构建链接的承诺。
我认为问题是在你的loadProjectList函数。因为.then()应该接收在结果时调用的函数。通常是函数返回链承诺。
但是在您的例子中,您立即并行调用所有load。$scope传递有点复杂。但是我认为你的代码应该是这样的
//this fn is called immediatly on chain creation
var loadProjectList = function ($scope) {
//this fn is called when previous promise resolves
return function(data) {
//don't add error handling here
ProjectService.getAll().then(...)
}
}
这会导致您可能想要的串行加载。(只需注意:为正确的方式并行执行$q。
最后,你应该只在ensureTypesLoaded中有错误处理程序,而不是在每个promise中。