2016-08-05 33 views
6

Im khá mới đối với RxJ và tôi muốn hiểu cách tốt nhất là làm việc với Rx kết hợp với Lời hứa.RxJs Tạo quan sát từ kết quả Hứa hẹn

Điều tôi muốn tạo là dịch vụ trong Góc hoạt động giống như mẫu điều phối sự kiện và phát ra sự kiện khi lời hứa hoàn tất. Những gì tôi cũng yêu cầu là, nếu không có (sự kiện) thuê bao quan sát không bao giờ được gọi. Điều cuối cùng tôi muốn xảy ra là mọi người đăng ký tiếp theo có thể nhận được kết quả tương tự mà không kích hoạt yêu cầu khác đối với máy chủ. tôi đã quản lý để thực hiện giải pháp của riêng tôi ở đây:

// ... CountryService code 

var COUNTRIES_LOADED = Rx.Observable 
    .create(function (observer) { 
     $http 
      .get('/countries') 
      .then(function (res) { 
       observer.onNext(res); 
      }, function (err) { 
       observer.onError(err); 
      }) 
      .finally(function() { 
       observer.onCompleted(); 
      }); 
    }) 
    .shareReplay(); 

Bây giờ bất cứ lúc nào tôi đăng ký một "người nghe" mới để chịu các quan sát sẽ được kéo. Mọi người đăng ký mới sẽ nhận được giá trị được lưu trong bộ nhớ cache mà không cần chạm lại vào máy chủ.

Vì vậy, bên "người tiêu dùng" của tôi (góc Directive) Tôi muốn làm một cái gì đó như thế này:

// ... countryInput directive code: 

COUNTRIES_LOADED.subscribe(function (response) { 
    // Fill in countries into scope or ctrl 
    scope.countries = response.countries; 
}); 

Bất kỳ thuê bao trong tương lai để người quan sát COUNTRIES_LOADED PHẢI KHÔNG kích hoạt một yêu cầu $ http. Tương tự như vậy, nếu chỉ thị không bao giờ được bao gồm trên trang, $ http sẽ không bao giờ được gọi.

Giải pháp ở trên hoạt động, tuy nhiên tôi không biết về những hạn chế tiềm ẩn và tác động bộ nhớ của phương pháp này. Đây có phải là giải pháp hợp lệ không? Có cách nào tốt hơn/thích hợp hơn để đạt được điều này bằng cách sử dụng RxJs?

Rất cám ơn!

+1

kiểm tra liên kết này sử dụng rxjs với angularjs http://cvuorinen.net/2016/05/using-rxjs-observables-with-angularjs-1/ –

+0

giải pháp của bạn có vẻ ổn, tôi không nghĩ rằng bạn có thể nghĩ ra điều gì đó tốt hơn thế này. – estus

Trả lời

1

Bạn đã cố gắng sử dụng API fromPromise() của rxjs5?

Kiểm tra tài liệu của tài liệu here!

+0

Có, tôi nhận thức được từTừ đó, nhưng điều đó chỉ xảy ra khi đã có lời hứa. Những gì tôi yêu cầu là một cuộc gọi $ http không bao giờ được thực hiện nếu không có người đăng ký nào có thể quan sát được – Max101

1

Đây là cách bạn có thể sử dụng Đài quan sát Cho phép nói rằng bạn có phương thức được gọi là getuser(username).

//Returns an observable 
getUser(username){ 
    return $http.get(url) 
     .map(res => res.json()); 
} 

Và bạn có thể sử dụng nó như dưới đây

getUser.subscribe(res => console.log(response)); 

NHƯNG nếu bạn muốn sử dụng những lời hứa

//Returns an Promise 
//Donot forget to import toPromise operator 
getUser(username){ 
    return $http.get(url) 
     .map(res => res.json()) 
     .toPromise(); 
} 

Và bạn có thể sử dụng nó như dưới đây

getUser.then(res => console.log(response)); 
+0

Ok xin lỗi, có lẽ câu hỏi không rõ ràng lắm. Tôi biết làm thế nào để sử dụng và tiêu thụ các quan sát, Những gì tôi muốn biết là làm thế nào để "bọc" một cuộc gọi HTTP bên trong một quan sát mà chỉ được gọi là nếu VÀ CHỈ nếu có/là bất kỳ thuê bao. – Max101

+0

Vấn đề lớn với câu trả lời này là '$ http.get' * không * trả về một Quan sát. Nó trả về một lời hứa. Đó là sự khác biệt lớn giữa 'Http' của Angular và '$ http' của AngularJS. – daemonaka

4

tôi tìm thấy câu trả lời ở đây (Chỉ hơi khác một chút ntly tên) rxjs using promise only once on subscribe

Vì vậy, ví dụ tôi câu trả lời là đơn giản như:

var loadCountries = function() { return $http.get('/countries'); }; 

var observable = Rx.Observable.defer(loadCountries).shareReplay(); 
2

Sử dụng Rx.Observable.fromPromise(promise)

fromPromise:

Chuyển đổi một Promises/A + đặc tả tuân thủ Promise và/hoặc ES2015 tuân thủ Lời hứa hoặc chức năng của nhà máy trả về lời hứa với số Trình tự quan sát được.

dụ:

var source = Rx.Observable.fromPromise(promise); 

var subscription = source.subscribe(
    function (x) { 
    console.log('Next: %s', x); 
    }, 
    function (err) { 
    console.log('Error: %s', err); 
    }, 
    function() { 
    console.log('Completed'); 
    }); 
Các vấn đề liên quan