http.post에서 응답을 기다리는 동안 어떻게 취소하는가?
이것은 각성분에서 나온 코드 입니다.검색 구성 요소:characterIndexes
검색 결과의 배열이다.
검색 결과를 트리거하는 검색 상자에 입력하면searchtrigger
, 또는searchEmptyTrigger
내용에 따라첫 번째 결과를 얻은 후 나는 다른 작업을 수행해야 한다.http.post()
인덱스에 속한 이름을 가져와 내가 정렬할 수 있도록(코드에서 해당 부분을 생략)그런 다음 결과를characterIndex
-배열.
비슷한 일이 일어날 때도 있다.searchEmptyTrigger
트리거됨.다음 항목만 제외하고characterIndex
-어레이는 그냥 비워두고 http-htp는 필요 없다.
내가 우연히 마주친 문제는 어떤 경우에는 언제인가 하는 것이다.searchEmptyTrigger
, 에에서 codesearchtrigger
아직 실행 중임(http-htp로 인한 지연으로 인해)
그 결과는 이다.characterIndexes
먼저 비어있다., 의 http-request에서 채워질 이다.searchtrigger
.
그래서 중요한 질문은 '대답을 기다리는 동안 달리기를 취소하는 방법'이다.
public characters: any[];
public characterIndexes: number[];
let searchBox = document.getElementById('search-box');
let searchTrigger = fromEvent(searchBox, 'input')
.pipe(
map((event: any) => event.target.value ),
filter( text => text.length > 2 ),
debounceTime( 500 ),
distinctUntilChanged(),
switchMap( text => ajax(`https://esi.evetech.net/v2/search/?categories=character&datasource=tranquility&language=en-us&search=^${text}&strict=false`)
)
);
let searchEmptyTrigger = fromEvent(searchBox, 'input')
.pipe(
map((event: any) => event.target.value ),
filter( text => text.length <= 2 )
);
searchTrigger.subscribe( response => {
if( response.response.character ){
let characterIndexes = response.response.character;
this.http.post('https://esi.evetech.net/latest/universe/names/?datasource=tranquility', characterIndexes)
.subscribe( (charactersInfo: any[]) => {
// do some stuff with this.characterIndexes and this.characters = [];
});
} else {
this.characterIndexes = [];
this.characters = [];
}
});
searchEmptyTrigger.subscribe( () => {
// reset values
this.characterIndexes = [];
this.characters = [];
});
PS: 나는 또한 http 요청을 취소할 수 있는 위의 코드와 동일한 작업을 수행하는 대체 접근법에 대해 개방적이다.
나는 당신이 a를 사용해야 한다고 생각한다.takeUntil(searchEmptyTrigger)
.
this.http.post('https://esi.evetech.net/latest/universe/names/?datasource=tranquility', characterIndexes)
.pipe(takeUntil(searchEmptyTrigger)) // make sure to cancel the post if `searchEmptyTrigger` emits
.subscribe( (charactersInfo: any[]) => {
// do some stuff with this.characterIndexes and this.characters = [];
});
PS, 당신은 당신의 전체 코드를 훨씬 더 적은 코드로 완전히 단순화할 수 있다.
를 .subscription
안쪽에subscription
, 당신의 것과 같은post
부탁한다
연산자를 사용하여 병합할 수 있다.다 쓰기 귀찮다 :d
이렇게 해 봐...
예 : 개념은 ~이다.unsubscribe
관측할 수 있는 물체...
const request = this.searchService.search(this.searchField.value)
.subscribe(
result => { this.result = result.artists.items; },
err => { this.errorMessage = err.message; },
() => { console.log('Completed'); }
);
request.unsubscribe(); // <-- Hear you can cancel the API request..
//Just set in when you need to cancel. It will works fine.
// E.x use with timeout or delay option of observable.
}
내가 알아냈다고 생각한다.뭐가 잘못됐는지 먼저 설명해보겠다, 그 후에 내 해결책을 검토하겠다.
문제
문제의 코드에는 문제가 있었다.새 값이 나오기 전에 이미 http-request를 실행했을 것이다.searchTrigger
, 그러나 지금은 아니다.searchTriggerEmpty
그러므로searchTrigger
다음에 방출될 수 있음searchTriggerEmpty
이 센 searchTrigger
먼저 시작되었었다.
해결책
해결책은 배출 순서를 고치는 것이었다.그렇게 하려면 요청이 있기 전에 이벤트를 내보내야 한다.그리고 새 이벤트가 트리거되는 경우 이전 이벤트를 취소해야 한다(switchMap
sufficient ).
코드 설명
- 그
searchTrigger
누군가가 에 입력하면 이벤트를 내보낸다.searchBox
. - 일부 파이프가 추가되었다.
debounceTime( 500 )
그리고distinctUntilChanged()
이벤트가 너무 자주 트리거되는 것을 방지하십시오. - 그
map
파이프는 searchBox에서 값 유형을 반환한다. - 그
switchMap
그 안에 조건부 진술이 있다.여기서 진행하기에 가장 좋은 방법이 선택된다. - 문자열이 2자 이상일 경우 문자열을 볼 수 있다.인덱스(일부 http-requests를 수행하고 처리함으로써 인덱스 생성).
- 문자열이 2자 미만일 경우 빈 배열을 직접 반환한다.
- a를 사용하는 이유
switchMap
여기서 현재 보류 중인 프로세스가 새로운 값이 방출될 때 취소될 것이다. - 에 가입하여
searchTrigger
우리는 이제 최신 검색 결과를 처리할 수 있다. - 내가 사용했던 기능도 제공했다.
process_searchString()
그래서 당신은 그것이 무엇을 하는지 더 잘 알 수 있다.
코드
let searchBox = document.getElementById('search-box');
let searchTrigger = fromEvent(searchBox, 'input')
.pipe(
debounceTime( 500 ),
distinctUntilChanged(),
map((event: any) => event.target.value ),
switchMap( searchString => {
if( searchString.length > 2 ){
return this.process_searchString( searchString );
} else if ( searchString.length <= 2 ) {
return of( [] );
}
}),
);
searchTrigger.subscribe( ( characterIndexes: number[] ) => {
this.characterIndexes = characterIndexes;
this.characters = [];
if( characterIndexes.length > 0 ){
this.load_10characters();
}
});
고지 사항:이 글을 쓰는 순간 나는 rxjs를 사용하는 법을 막 배웠다.그래서 만약 여러분이 개선되어야 할 어떤 것을 본다면 코멘트에서 떨어뜨려라.
PS: 관심 있는 사람들을 위해 이 비디오는 스위치맵을 나보다 더 잘 설명하고 있다(또한 재미있고). https://www.youtube.com/watch?v=rUZ9CjcaCEw
엑스트라process_searchString()
:
private process_searchString( searchString: string ): Observable<number[]>{
return new BehaviorSubject( searchString )
.pipe(
concatMap( ( text: string ) => this.request_characterSearch( text ) ),
concatMap( ( response: any ) => {
if( response.character ){
return this.request_characterNames( response.character )
} else {
return of([]);
}
}),
map( (charactersInfo: any[]) => this.sort_alphabetically( charactersInfo ) ),
map( (charactersInfo: any[]) => charactersInfo.map( characterinfo => characterinfo.id ) ),
);
}
'Programing' 카테고리의 다른 글
python2에서 drit.items()와 drit.iteritems()의 차이점은 무엇인가? (0) | 2022.04.04 |
---|---|
Python에서 어떻게 시간 지연을 할 수 있을까? (0) | 2022.04.04 |
RxJs 5 공유() 운영자는 어떻게 작동하나? (0) | 2022.04.03 |
반응-원호 연결 AddEventListener가 작동하지 않음 (0) | 2022.04.03 |
Vuejs3 : 다음 Vue-router-next의 louer.js로 "transition"을 렌더링하려면 어떻게 해야 하는가? (0) | 2022.04.03 |