我想创建一个函数来在服务器中发出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而不是每次都调用一次请求。
我该怎么办?
答案 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);
哪个应该只使用最后一个参数发出一个请求并将其返回给侦听器。