如何使用Rxjs 5限制服务器请求?

时间:2017-11-02 17:17:34

标签: javascript rxjs rxjs5

我想创建一个函数来在服务器中发出HTTP PUT请求,但是如果在该时间间隔内多次调用该函数,则每隔500ms使用最后一个调用参数,并且如果它仍在进行中则取消最后一个请求。

我研究并提出了这个解决方案:

const { Observable } = require('rxjs/Observable')
const { Subject } = require('rxjs/Subject')
const { switchMap, auditTime } = require('rxjs/operators')

// Simulate HTTP request
function makeRequest (val) {
  return Observable.create(observer => {
    console.log('Request:', val);
    observer.next(val);
    observer.complete();
  });
}

const toUpdateStream = new Subject();
const notifier$ = toUpdateStream.pipe(
  auditTime(500),
  switchMap(val => makeRequest(val))
);


function updateThrottle (val) {
  return Observable.create(observer => {
    const lastUpdate$ = notifier$.subscribe(res => {
      observer.next(res);
      observer.complete();
      lastUpdate$.unsubscribe();
    });
    toUpdateStream.next(val);
  });
}

// Try to update 3 times with different parameters
updateThrottle(10).subscribe(val => { console.log('1:', val); });
updateThrottle(20).subscribe(val => { console.log('2:', val); });
updateThrottle(30).subscribe(val => { console.log('3:', val); });

输出结果为:

Request: 30
1: 30
Request: 30
2: 30
Request: 30
3: 30

问题在于我只需要使用30而不是每次都调用一次请求。

我该怎么办?

2 个答案:

答案 0 :(得分:2)

因此,只有当值已从之前的发射更改时,您才想将值传递给WARNING in C:/Data/.../letsTest.jsx There are multiple modules with names that only differ in casing. This can lead to unexpected behavior when compiling on a filesystem with other case-semantic. Use equal casing. Compare these module identifiers: * C:\Data\...\node_modules\babel-loader\lib\index.js?presets[]=es2015&presets[]=react&presets[]=stage-0&presets[]=stage-2!C:\Data\...\letsTest.jsx Used by 4 module(s), i. e. multi C:/Data/Doc/13/13080801/LetsTest/letsTest.jsx * C:\Data\...\node_modules\babel-loader\lib\index.js?presets[]=es2015&presets[]=react&presets[]=stage-0&presets[]=stage-2!c:\Data\...\letsTest.jsx Used by 1 module(s), i. e. C:\Data\...\node_modules\babel-loader\lib\index.js?presets[]=es2015&presets[]=react&presets[]=stage-0&presets[]=stage-2!C:\Data\...\r1HeadLearning.js pairwise运算符适用于此用例。

auditTime

您可以使用const notifier$ = toUpdateStream.pipe( startWith(null), pairwise(), // Emit the previous and current search options filter(([oldSearch, newSearch]) => oldSearch !== newSearch), map(([oldSearch, newSearch]) => newSearch), auditTime(500), switchMap(val => makeRequest(val)) ); 而不是pairwise(),而是做同样的事情。

答案 1 :(得分:0)

在尝试了一些东西后,我最终得到了这个最终解决方案:

$("#contactForm").submit(function(event){
// cancels the form submission
event.preventDefault();
submitForm();
});

function submitForm(){
// Initiate Variables With Form Content
var name = $("#name").val();
var email = $("#email").val();
var message = $("#message").val();

$.ajax({
    type: "POST",
    url: "index2.php",
    data: "name=" + name + "&email=" + email + "&message=" + message,
    success : function(text){
        if (text == "success"){

            formSuccess();
        }
    }
});
}
function formSuccess(){

$( "#msgSubmit" ).removeClass( "hidden" );
}

var confirmSubmit = true;

$('form').submit(function(e) {
  if (confirmSubmit) {
   e.stopPropagation();

if (confirm('Are you sure you want to send this form?')) {
  confirmSubmit = false;

  $('form').submit();
}else{
  alert("The form was not submitted.");
  }
  }
});

日志:

const { Observable } = require('rxjs/Observable')
const { Subject } = require('rxjs/Subject')
const { auditTime, switchMap } = require('rxjs/operators')

// Simulate log with timestamp
const log = msg => {
  const d = new Date();
  console.log(d.getSeconds() +'.'+ d.getMilliseconds() +' - '+ msg);
}

// Simulate HTTP request that takes 750ms
function makeRequest (val) {
  return Observable.create(observer => {
    const timeout = setTimeout(() => {
      log('Request: '+ val);
      observer.next('R'+ val);  // Mock the HTTP response
      observer.complete();
    }, 750);
    return () => clearTimeout(timeout);
  });
}

const toUpdateStream$ = new Subject();
const updatedStream$ = new Subject();
const filter$ = toUpdateStream$.pipe(
  auditTime(500),
  switchMap(val => makeRequest(val))
);
filter$.subscribe(val => updatedStream$.next(val));

function updateThrottle (val) {
  return Observable.create(observer => {
    const lastUpdate = updatedStream$.subscribe(res => {
      observer.next(res);
      observer.complete();
      lastUpdate.unsubscribe();
    });
    toUpdateStream$.next(val);
  });
}

log('Start');

// Try 3 requests and the last one (the 30) gets processed
updateThrottle(10).subscribe(val => log('1: '+ val));
updateThrottle(20).subscribe(val => log('2: '+ val));
updateThrottle(30).subscribe(val => log('3: '+ val));

// Try to make more requests when the current one isn't finished
setTimeout(() => {
  // This one cancels the last one
  updateThrottle(40).subscribe(val => log('4: '+ val));
  updateThrottle(50).subscribe(val => log('5: '+ val));
  updateThrottle(60).subscribe(val => log('6: '+ val)); // This gets processed
}, 600);

哪个应该只使用最后一个参数发出一个请求并将其返回给侦听器。