さまざまな Deferred/promise ライブラリのドキュメントでは、1 つまたは 2 つの関数/メソッドを連鎖させて成功またはエラーを解決または拒否するなど、非常に単純なユース ケースを扱っていることがよくあります。
しかし、より複雑なユース ケース (5 つ以上の関数/メソッドのチェーン、ネストされた Deferred、他の Deferred 内から promise を返す) になると、私は手ぶらで来て、非常にイライラします。
たとえば、2 つのネストされた関数を含む関数があるとします。各子関数は promise を返し、親関数が子の成功/失敗の結果を返すようにします。
var saveUser = function(user) {
var saveNewUser = function(user) {
var deferred = when.defer();
user.save(function (err) {
if (err) {
deferred.reject();
}
else {
// forcing a rejection here for testing purposes
deferred.reject(6);
}
});
return deferred.promise;
}
var supplyUserCollections = function() {
var deferred = when.defer();
deferred.reject();
return deferred.promise;
}
return saveNewUser(user).then(supplyUserCollections(), function() {
console.log('failed to save new user');
}).then(function(data) {
console.log('succeeded to do everything');
}, function() {
console.log('failed to seed new user collections');
});
}
これは機能しません。console.log
奇妙なことに、両方の子関数に拒否/失敗を強制しているにもかかわらず、「すべての実行に成功しました」が発生します。a の最初のパラメーター.then
が成功例であるため、なぜこれが起こっているのか本当にわかりません。さらに、親関数saveUser
が次のような別の広範な promise チェーンの一部であると仮定します。
dropExistingCollections(collections).then(saveEntities(albums), function() {
console.log('failed to drop existing collections');
}).then(saveEntities(movies), function() {
console.log('failed to save all albums');
}).then(saveEntities(games), function() {
console.log('failed to save all movies');
}).then(saveUsers(users), function() {
console.log('failed to save all games');
}).then(function(data) {
console.log(data);
console.log('successfully saved all seed data');
res.send('database data wiped and re-seeded');
}, function() {
console.log('failed to save all users');
});
saveUser
解決済み/拒否された Deferred を返すすべての単純な関数である、残りの関数と連鎖可能な方法でプロミスを適切に返す方法がよくわかりません。
Deferreds/promise のこれらのより複雑なユースケースのいくつかがどのように処理されることになっているのかについて、より明確にしたいと思います。これは明らかに非常に密度の高いトピックであり、私が見つけた資料のほとんどは、私にとって特にうまく共鳴するものではありません.