2017-08-23 20 views
7

Khi tôi cố gắng tạo nhiều yêu cầu http qua dịch vụ http ở góc 4, yêu cầu trước đó bị hủy bỏ vào Chrome (nhưng chúng đạt đến máy chủ). Ví dụ:góc 4. Một loạt các yêu cầu HTTP GET hủy

const obs1 = this.http.get(`${API_URL}/transitions`); 
const obs2 = this.http.get(`${API_URL}/states`); 
obs1.subscribe(); 
obs2.subscribe(); // this will cancel obs1's http request 

Nhưng nếu tôi thay .subscribe() để .publish().connect() như trên, nó sẽ làm việc một cách chính xác (không hủy bỏ)

const obs1 = this.http.get(`${API_URL}/transitions`); 
const obs2 = this.http.get(`${API_URL}/states`); 
obs1.publish().connect(); 
obs2.publish().connect(); 

Hoặc nếu tôi hợp nhất hai Observables một và sau đó được đăng ký như trên, nó sẽ hoạt động chính xác quá

const obs1 = this.http.get(`${API_URL}/transitions`); 
const obs2 = this.http.get(`${API_URL}/states`); 
Observable.merge(obs1, obs2).subscribe() 

Tại sao tôi phải đối mặt với hành vi này? Tôi cần hiểu, không bỏ qua. Làm thế nào tôi có thể làm cho hàng loạt các yêu cầu mà không sáp nhập, forking vv?

Trả lời

6

Tôi đã tìm thấy một lý do tiềm năng của hành vi này.

Nhờ https://github.com/ghetolayhttps://github.com/dklmuc

Chúng tôi phát hiện ra rằng góc sẽ hủy bỏ yêu cầu http rất nhanh mà không cần bất kỳ callback. Vì vậy, bạn phải vượt qua onNext trong đăng ký

Từ https://github.com/ghetolay:

ok đó là tình trạng đua Tôi nghĩ

nó sẽ luôn luôn gọi xhr.abort() trên teardown

nếu kết nối vẫn được coi là mở bằng trình duyệt nó sẽ đóng nó lại, nếu không có lẽ không làm gì

vì vậy khi bạn có một xử lý rất nhanh của phản ứng (như không gọi lại thực sự là rất nhanh) nó có thể hủy bỏ kết nối đó là vẫn được coi là mở

một này hoạt động một cách chính xác:

for (let i = 1; i < 50; i++) { 
    http.get(`https://swapi.co/api/people/${i}`).subscribe((result) => { 
     console.log(i, result); 
    }); 
} 
+0

Bây giờ tôi cảm thấy tồi tệ, vì tôi sẽ bình luận về điều đó nhưng chỉ cho rằng ví dụ của bạn đã được đơn giản hóa. Nếu bạn cần thực hiện yêu cầu http mà không cần đăng ký. Bạn có thể gọi 'http.get (...). (1)' sẽ đăng ký và hủy đăng ký sau khi mục đầu tiên được tìm nạp. – cgTag

+0

@ctTag Mất (1) sẽ gọi sự kiện yêu cầu mà không có phương thức đăng ký không? – WimmDeveloper

+0

@ctTag Không, nó sẽ không. Đã kiểm tra ngay bây giờ. Nhưng tôi vừa mới nhận ra rằng đối với các phương thức http rất hợp lý để sử dụng '.take (1)' – WimmDeveloper

0

này đã làm với quan sát bị hủy bỏ, mặc dù tôi phải thừa nhận tôi không biết nguyên nhân gốc rễ cho vấn đề bạn gặp phải.

Tôi chạy vào một vấn đề tương tự bằng cách sử dụng ngrx/hiệu ứng mô-đun. Trình xử lý hành động đã thực hiện các yêu cầu tới một dịch vụ bằng cách sử dụng toán tử chuyển đổi bản đồ ngrx. Tất cả ngoại trừ yêu cầu cuối cùng sẽ bị hủy. Thay đổi nó để hợp nhất bản đồ cố định vấn đề. Dưới đây là mã số

@Effect() 
    loadSomeData$: Observable<Action> = this.actions$ 
      .ofType(SomeActions.Load_Data) 
      .mergeMap((id) => 
        this.someService.getSomething(id) 
          .map((someEntity) => new SomeActions.LoadDataSuccess(someEntity) 
          ).catch((x, y) => { 
            console.error('Error occured'); 
            return Observable.of(new SomeActions.LoadDataFailed(id)); 
          } 
          )); 

Sao chép phần liên quan của ngrx tại đây.

https://www.learnrxjs.io/operators/transformation/switchmap.html

Sự khác biệt chính giữa switchMap và khai thác phẳng khác là hiệu ứng hủy. Trên mỗi phát xạ, bên trong có thể quan sát được trước đó (kết quả của chức năng bạn đã cung cấp) bị hủy và có thể quan sát được mức quan sát mới. Bạn có thể nhớ điều này bằng cách chuyển cụm từ sang một quan sát mới.

Các vấn đề liên quan