RxJS:请求完成后再次开始发布

时间:2015-01-07 16:49:45

标签: jquery ajax observable rxjs

我正在使用RxJS来收听表单提交事件,并通过AJAX提交它(它是一个奇怪的代码,但我现在只是尝试使用RxJS,所以请耐心等待我)。我想要做的只是在请求不在进行时才允许提交。

到目前为止我的代码看起来像这样(并且是#34;工作"):

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));

1 个答案:

答案 0 :(得分:3)

好问题。在first()之后使用submit仅允许一次提交,并在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(); });