複雑なリソースロードシーケンスでは、約束を編集する方法
-
21-12-2019 - |
質問
角度コードでは、このような連鎖の約束を持っています:
// a function in LoaderService module.
var ensureTypesLoaded= function(){
return loadContainerTypes($scope).then(loadSampleTypes($scope)).then(loadProjectList($scope)).then(loadSubjectTypes($scope));
}
.
これらの関数のそれぞれは、リソースから物事をロードし、エラーと成功の$ 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!');
});
};
.
コントローラの初期化のコード内で使用することは、
// 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のすべてが解決された後に()内のものを呼び出す必要があります。
連鎖約束の正しい建物で私を助けてください。
解決
問題がLoadProjectList関数にあると考えています。.then()は、結果として呼び出される関数を受け取るべきです。通常チェーンの約束を返す機能です。
しかしあなたの場合はあなたはすべての負荷を直ちに並行して呼び出します。$範囲通過ではほとんど複雑です。しかし、私はあなたのコードがこのようなように見えるべきだと思います
//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が使用されている場合)
最後に、それぞれの約束にはなく、EnvureTypesLoadedにのみエラーハンドラを持つ必要があります。
所属していません StackOverflow