RxJS:请求完成后再次开始发布
RxJS: Start publishing again when request is done
我正在使用 RxJS 来监听表单提交事件,并通过 AJAX 提交它(这是一段奇怪的代码,但我现在只是在试验 RxJS,所以请耐心等待).我想做的是仅在请求未进行时允许提交。
到目前为止,我的代码看起来像这样(而且是 "working"):
Rx.DOM.submit(formEl)
.map(function(event){ event.preventDefault(); return event; })
.map(function(){ return getEmailAddress(formEl); })
.subscribe(function(email){
submitToMailChimp(url, email).done(showMailChimpThanks(orbitInstance)).fail(showMailChimpError);
});
我的问题是我不确定如何实现一些东西来适应这个限制(看到 skipUntil 但不太确定在这种情况下如何处理)。所以我的问题是:我如何 (a) 在我的 Ajax 请求完成之前阻止提交,以及 (b) 优化我的代码以使 Ajax 请求位于链的末尾,这样我就可以 subscribe
它的结果,而不是这种奇怪的混合混搭。
最终解:
var submissions = Rx.DOM.submit(formEl);
submissions.subscribe(preventDefaultEvent);
var requests = submissions
.first()
.map(getEmailAddress(formEl))
.flatMap(submitToMailChimp(url))
.catch(showMailChimpError(submitButton))
.repeat();
requests.subscribe(showMailChimpThanks(orbitInstance, submitButton));
好问题。在 submit
之后使用 first()
只允许一次提交,并且在 ajax 请求完成后(我们将通过 flatMap
调用),这个可观察对象将完成(因为 first
).因此,我们附加一个 repeat()
以在第一个提交完成后开始监听下一个提交。因为我想您不想在 ajax 调用之一失败时停止流,所以我们会将您的 ajax 请求的结果转换为 Error
或结果和流此 "Either" 作为数据(参见 this question)
棘手的部分是您还想确保每次都调用 preventDefault
,即使正在处理当前提交并且我们当前没有监听 submit
。在我看来,这是一个具有不同观察要求的不同动作,因此我们应该将它写成一个单独的查询。因此我们最终得到:
var submissions = Rx.DOM.submit(formEl);
// send ajax requests on submissions
submissions
.first()
.flatMap(function (event) {
var email = getEmailAddress(formEl);
return submitToMailChimp(url, email)
.then(
function (v) { return v; },
function (e) { return new Error(e); });
})
.repeat()
.subscribe(function (result) {
if (result instanceof Error) {
showMailChimpError(result);
}
else {
showMailChimpThanks(instance);
}
});
// prevent defaults
submissions.subscribe(function (ev) { ev.preventDefault(); });
我正在使用 RxJS 来监听表单提交事件,并通过 AJAX 提交它(这是一段奇怪的代码,但我现在只是在试验 RxJS,所以请耐心等待).我想做的是仅在请求未进行时允许提交。
到目前为止,我的代码看起来像这样(而且是 "working"):
Rx.DOM.submit(formEl)
.map(function(event){ event.preventDefault(); return event; })
.map(function(){ return getEmailAddress(formEl); })
.subscribe(function(email){
submitToMailChimp(url, email).done(showMailChimpThanks(orbitInstance)).fail(showMailChimpError);
});
我的问题是我不确定如何实现一些东西来适应这个限制(看到 skipUntil 但不太确定在这种情况下如何处理)。所以我的问题是:我如何 (a) 在我的 Ajax 请求完成之前阻止提交,以及 (b) 优化我的代码以使 Ajax 请求位于链的末尾,这样我就可以 subscribe
它的结果,而不是这种奇怪的混合混搭。
最终解:
var submissions = Rx.DOM.submit(formEl);
submissions.subscribe(preventDefaultEvent);
var requests = submissions
.first()
.map(getEmailAddress(formEl))
.flatMap(submitToMailChimp(url))
.catch(showMailChimpError(submitButton))
.repeat();
requests.subscribe(showMailChimpThanks(orbitInstance, submitButton));
好问题。在 submit
之后使用 first()
只允许一次提交,并且在 ajax 请求完成后(我们将通过 flatMap
调用),这个可观察对象将完成(因为 first
).因此,我们附加一个 repeat()
以在第一个提交完成后开始监听下一个提交。因为我想您不想在 ajax 调用之一失败时停止流,所以我们会将您的 ajax 请求的结果转换为 Error
或结果和流此 "Either" 作为数据(参见 this question)
棘手的部分是您还想确保每次都调用 preventDefault
,即使正在处理当前提交并且我们当前没有监听 submit
。在我看来,这是一个具有不同观察要求的不同动作,因此我们应该将它写成一个单独的查询。因此我们最终得到:
var submissions = Rx.DOM.submit(formEl);
// send ajax requests on submissions
submissions
.first()
.flatMap(function (event) {
var email = getEmailAddress(formEl);
return submitToMailChimp(url, email)
.then(
function (v) { return v; },
function (e) { return new Error(e); });
})
.repeat()
.subscribe(function (result) {
if (result instanceof Error) {
showMailChimpError(result);
}
else {
showMailChimpThanks(instance);
}
});
// prevent defaults
submissions.subscribe(function (ev) { ev.preventDefault(); });