[英]Using Bacon.js to disable submit button while deferreds are “pending”
我有一個表單,其中有許多圖像網址 - 后端持久保存網址字符串,圖像直接上傳到S3。 我想在上傳過程中使用Bacon.js流來處理禁用/啟用表單的提交按鈕。
我嘗試過各種方法(使用Bacon.fromPromises流,使用fromPromise -d deferreds流和一個原始延遲的總線並試圖手動區分兩者)但是沒有找到a)工作的解決方案按照預期和b)感覺我不是在和圖書館作戰。
事情就是這樣,但如上所述,提交按鈕會過早地重新啟用。
function toResultStream(promise) {
return Bacon.fromPromise(promise)
}
var deferreds = $('a').asEventStream('click', function (event) {
event.preventDefault();
var deferred = $.Deferred();
// simulate upload
setTimeout(function () {
deferred.resolve(true);
}, _.random(200, 1600))
setTimeout(function () {
deferred.rejectWith(false);
}, _.random(200, 1600))
return deferred;
});
deferreds.onValue(function () {
$('#submit').attr('disabled', true);
})
// only takes completed deferreds into consideration
var ongoingSearch = deferreds.flatMap(function (d) {
return toResultStream(d);
})
.mapError(true)
.onValue(function () {
$('#submit').attr('disabled', false);
});
*更新
@ mjs2600的回答足以讓我找到解決方案。
這是我最終做的事情:
var bus = new Bacon.Bus();
var deferreds = $('a').asEventStream('click', function (event) {
// ...
bus.push(-1);
// ...
});
var ongoingSearch = deferreds
.flatMap(toResultStream)
.mapError(1)
.merge(bus)
.scan(0, function (memo, n) { return memo + n; })
.onValue(function (value) {
var disabled = value < 0;
$('#submit').attr('disabled', disabled);
});
我知道使用Buses是不受歡迎的,所以如果有人建議我如何用流來實現相同的行為,我非常希望看到它。
如果您知道要上傳的網址數量,可以添加像這樣的skip
來忽略除最后一個網址之外的所有響應。
var numStreams = 1;
var ongoingSearch = deferreds.flatMap(function (d) {
return toResultStream(d);
})
.mapError(true)
.skip(numSteams-1)
.onValue(function () {
alert('fooo');
$('#submit').attr('disabled', false);
});
我發現你發布的代碼有點令人擔憂的一件事是這些流永遠不會終止。 您可以考慮重構,以便clickSearch創建proceedSearch,並在所有流完成后終止。 (例如, merge
上傳流並重新啟用該合並的onEnd
中的按鈕。)
當你發出請求時,我會制作一個流並將其映射到-1,當你得到響應時我會映射到+1。 然后,您可以在流上運行折疊,並在等於0時啟用該按鈕。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.