Programing

http.post에서 응답을 기다리는 동안 어떻게 취소하는가?

c10106 2022. 4. 4. 19:01
반응형

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먼저 시작되었었다.

해결책

해결책은 배출 순서를 고치는 것이었다.그렇게 하려면 요청이 있기 전에 이벤트를 내보내야 한다.그리고 새 이벤트가 트리거되는 경우 이전 이벤트를 취소해야 한다(switchMapsufficient ).

코드 설명

  • 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 ) ),
    );
  }

참조URL: https://stackoverflow.com/questions/53056457/how-to-cancel-a-http-post-while-it-is-waiting-for-a-response

반응형