在 Angular 代码中,我有一个像这样的链式 promise :
// 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!');
});
};
我打算在 Controller 初始化的代码中使用 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
});
但是,这并不像我想要的那样工作。理想情况下,消息“在所有 promise 解决后我将在此处执行某些操作”必须在所有 promise 解决后出现。相反,我可以看到它早于列出的 EnsureTypesLoaded 函数中已解决的 Promise 的消息。
我想创建一个函数sureTypesLoaded,这样:
- 它返回一个 promise ,当所有链接的负载都得到解决时,该 promise 就得到解决;
- 如果任何“内部” promise 失败,该函数不应继续进行下一次调用,而是返回被拒绝的 promise 。
- 显然,如果我调用ensureTypesLoaded().then(...),则必须在ensureTypesLoaded内的所有内容都得到解决之后调用then()中的内容。
请帮助我正确构建链式 promise 。
最佳答案
我认为问题出在您的 loadProjectList 函数中。因为 .then() 应该接收在结果时调用的函数。通常是函数返回链式 promise 。
但在您的情况下,您立即并行调用所有负载。 $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.all 的使用)
最后,您应该仅在 EnsureTypesLoaded 中拥有错误处理程序,而不是在每个 Promise 中。
关于javascript - 如何在复杂的资源加载序列中正确链接 promise ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25032282/