我有一个表单,其中包含许多图片URL - 后端将URL字符串持久化,并且图片直接上传到S3。我想使用Bacon.js流来处理在上传过程中禁用/启用表单提交按钮。
我尝试了各种方法(使用Bacon.fromPromises的流流,使用fromPromise-d延迟的流和原始延迟的总线,并尝试手动区分两者),但没有找到既能够正常工作又不需要费力地与库对抗的解决方案。
目前情况如上所述,但是请注意,提交按钮会过早地重新启用。
我尝试了各种方法(使用Bacon.fromPromises的流流,使用fromPromise-d延迟的流和原始延迟的总线,并尝试手动区分两者),但没有找到既能够正常工作又不需要费力地与库对抗的解决方案。
目前情况如上所述,但是请注意,提交按钮会过早地重新启用。
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);
});
我知道使用总线不被推荐,如果有人能提供使用流来实现同样行为的建议,我将非常感激。