一部の呼び出しが機能し、他の呼び出しが失敗すると、$ q.all()で何が起こりますか?
私は次のコードを持っています:
var entityIdColumn = $scope.entityType.toLowerCase() + 'Id';
var requests = $scope.grid.data
.filter(function (rowData, i) {
return !angular.equals(rowData, $scope.grid.backup[i]);
})
.map(function (rowData, i) {
var entityId = rowData[entityIdColumn];
return $http.put('/api/' + $scope.entityType + '/' + entityId, rowData);
});
$q.all(requests).then(function (allResponses) {
//if all the requests succeeded, this will be called, and $q.all will get an
//array of all their responses.
console.log(allResponses[0].data);
}, function (error) {
//This will be called if $q.all finds any of the requests erroring.
var abc = error;
var def = 99;
});
すべての$ http呼び出しが機能すると、allResponses配列にデータが入力されます。
1つが失敗すると、2番目の関数が呼び出され、エラー変数に詳細が与えられることは私の理解です。
ただし、一部の応答が機能し、他の応答が失敗した場合に何が起こるかを誰かが説明してくれますか?
PromiseライブラリはQ
実装に基づいているため、最初のpromiseが拒否されるとすぐに、拒否コールバックがエラーで呼び出されます。他の約束が解決されるのを待ちません。 Q
https://github.com/kriskowal/q のドキュメントを参照してください。 Q.allの場合、これが言及されているものです
All関数は、値の配列のpromiseを返します。この約束が履行されると、配列には元の約束の履行値がそれらの約束と同じ順序で含まれます。指定された約束のいずれかが拒否された場合、返された約束はすぐに拒否され、残りのバッチを待機しません。
この質問が投稿されてからしばらく経ちましたが、おそらく私の答えが誰かを助けるかもしれません。私は、すべての約束を解決することで同様の問題を解決しましたが、返品があれば後で処理してエラーがないかどうかを確認できました。以下は、いくつかの画像アセットをプリロードするために使用した私の例です。
var loadImg = function(imageSrc) {
var deferred = $q.defer();
var img = new Image();
img.onload = function() {
deferred.resolve({
success: true,
imgUrl: imageSrc
});
};
img.onerror = img.onabort = function() {
deferred.resolve({
success: false,
imgUrl: imageSrc
});
};
img.src = imageSrc;
return deferred.promise;
}
後で、どれがエラーであるかを確認できます。
var promiseList = [];
for (var i = 0; i < myImageList.length; i++) {
promiseList[i] = loadImg(myImageList[i]);
}
$q.all(promiseList).then(
function(results) {
for (var i = 0; i < results.length; i++) {
if (!results[i].success) {
// these are errors
}
}
}
);
編集: Kris KowalのQでのみサポートされています-それでも有用な情報
失敗時にすぐに拒否せずにすべてを処理する場合は、allSettled
を使用します
ドキュメントの内容は次のとおりです。
すべての約束が履行または拒否されるのを待ちたい場合は、allSettledを使用できます。
Q.allSettled(promises)
.then(function (results) {
results.forEach(function (result) {
if (result.state === "fulfilled") {
var value = result.value;
} else {
var reason = result.reason;
}
});
});
ここに小さな答えがあります。このフィドルでは、何らかの約束でエラーが発生した場合の動作を確認できます。
$q.all([test1(), test2()]).then(function() {
// success
}, function() {
// error
});
角度で$ qにallSettled機能を追加する新しいangularパッケージを見つけました:
$ httpの約束のエラー状態を$ qに渡す前に単純に処理できませんか?約束は連鎖しているので、これはうまくいくはずです:
return $http.put('/api/' + $scope.entityType + '/' + entityId, rowData).then(function(r){return r;}, angular.noop);
明らかに、noopを任意の変換に変更できますが、これにより$q.all
失敗から。
私の場合、成功したか失敗したかに関係なく、最後の約束がいつ解決されたかを知る必要がありました。失敗するとすぐにダウンするため、$ q.allはオプションではありませんでした。すべてのデータが処理される(または処理されない)場合にのみユーザーをリダイレクトして、次のページにロードできるようにするためにこれが必要でした。だから私はこれで終わった:
私はそれがそれを行うには非常に不十分な方法であることを知っていますが、それは私のために働いた。