我有一个表单,其中有很多图片 url - 后端保留 url 字符串,图片直接上传到 S3。我想在上传过程中使用 Bacon.js 流来处理禁用/启用表单的提交按钮。
我尝试了各种方法(使用 Bacon.fromPromises 流,使用 fromPromise-d 延迟流和原始延迟总线并尝试手动区分两者)但没有找到解决方案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);
});
我知道使用总线是不受欢迎的,所以如果有人对我如何使用流实现相同的行为有建议,我非常希望看到它。
最佳答案
如果您知道要上传的 url 的数量,您可以像这样添加 skip
以忽略除最后一个 url 之外的所有响应。
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);
});
我对您发布的代码感到有点担心的是这些流永远不会终止。您可能会考虑进行重构,以便通过单击创建持续搜索,并在所有流完成后终止。 (例如,合并
上传流并在该合并的onEnd
中重新启用按钮。)
关于javascript - 使用 Bacon.js 在延迟为 "pending"时禁用提交按钮,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31393823/