Açık geçiş
Geri aramaların yuvalanmasına benzer şekilde, bu teknik kapaklara dayanır. Ancak, zincir düz kalır - sadece en son sonucu geçmek yerine, her adım için bir durum nesnesi geçirilir. Bu durum nesneleri, daha sonra gerekli olacak tüm değerleri ve geçerli görevin sonucunu teslim ederek önceki eylemlerin sonuçlarını biriktirir.
function getExample() {
return promiseA(…).then(function(resultA) {
// some processing
return promiseB(…).then(b => [resultA, b]); // function(b) { return [resultA, b] }
}).then(function([resultA, resultB]) {
// more processing
return // something using both resultA and resultB
});
}
Burada, bu küçük ok b => [resultA, b]
, resultA
her iki sonucun bir dizisini bir sonraki adıma geçiren işlevdir . Bu, tek değişkenlerde tekrar parçalamak için parametre yıkım sözdizimini kullanır.
ES6 ile yıkım yapılmadan önce, .spread()
birçok söz kütüphanesi ( Q , Bluebird , when ,…) tarafından adlandırılan şık bir yardımcı yöntem sağlandı . Kullanılacak her dizi öğesi için bir tane olmak üzere birden fazla parametreli bir işlev alır .spread(function(resultA, resultB) { …
.
Elbette, burada ihtiyaç duyulan kapanma, bazı yardımcı işlevlerle daha da basitleştirilebilir, örn.
function addTo(x) {
// imagine complex `arguments` fiddling or anything that helps usability
// but you get the idea with this simple one:
return res => [x, res];
}
…
return promiseB(…).then(addTo(resultA));
Alternatif olarak, Promise.all
dizi için vaat üretmek için kullanabilirsiniz :
function getExample() {
return promiseA(…).then(function(resultA) {
// some processing
return Promise.all([resultA, promiseB(…)]); // resultA will implicitly be wrapped
// as if passed to Promise.resolve()
}).then(function([resultA, resultB]) {
// more processing
return // something using both resultA and resultB
});
}
Ve sadece dizileri değil, keyfi olarak karmaşık nesneleri de kullanabilirsiniz. Örneğin, farklı bir yardımcı işlevle _.extend
veya bu Object.assign
işlevde:
function augment(obj, name) {
return function (res) { var r = Object.assign({}, obj); r[name] = res; return r; };
}
function getExample() {
return promiseA(…).then(function(resultA) {
// some processing
return promiseB(…).then(augment({resultA}, "resultB"));
}).then(function(obj) {
// more processing
return // something using both obj.resultA and obj.resultB
});
}
Bu model düz bir zinciri garanti ederken ve açık durumdaki nesneler netliği artırabilirken, uzun bir zincir için sıkıcı olacaktır. Özellikle devlete sadece ara sıra ihtiyaç duyduğunuzda, hala her adımdan geçmeniz gerekiyor. Bu sabit arabirimle, zincirdeki tek geri çağrılar oldukça sıkı bir şekilde bağlanır ve değişime esnek değildir. Faktörleri tek adımlarla zorlaştırır ve geri çağrılar doğrudan diğer modüllerden sağlanamaz - her zaman durumu önemseyen demirbaş koduna sarılmalıdır. Yukarıdaki gibi soyut yardımcı işlevler ağrıyı biraz hafifletebilir, ancak her zaman mevcut olacaktır.
javascript
, diğer dilde alakalı. Ben sadece java ve jdeferred "zinciri kırmak" cevabını kullanıyorum