Sự khác biệt giữa Promise và Observables là gì?


1397

Sự khác biệt giữa PromiseObservabletrong Angular là gì?

Một ví dụ trên mỗi sẽ hữu ích trong việc hiểu cả hai trường hợp. Trong kịch bản nào chúng ta có thể sử dụng từng trường hợp?


23
Tôi sẽ đề nghị bạn đọc bài viết này; Lời hứa Angular2 vs có thể quan sát
erolkaya84

4
trong các thuật ngữ đơn giản hơn angular-2-training-book.rangle.io/handout/observables/ Lời
Pardeep Jain

3
Đối với bất kỳ ai đọc Q & A này - với tư cách là người tham gia vào cả hai thế giới từ người bảo trì, người nói và người dùng lâu năm PoV, tôi khuyến khích bạn đọc các tài liệu RxJS chính thức và tài liệu MDN về các lời hứa. Cá nhân tôi thấy các câu trả lời ở đây hoàn toàn sai lệch và không chính xác và tin rằng chúng là, trong khi với ý định tốt từ những người cố gắng giúp đỡ, rất có hại.
Benjamin Gruenbaum

1
Tôi muốn đề nghị bạn đọc tài liệu chính thức góc cạnh này angular.io/guide/compared-observables
fgul 24/03/19

Và đây là lý do tại sao các liên kết được coi là không thể chấp nhận như câu trả lời.
Dave

Câu trả lời:


1551

Lời hứa

Một Promisexử lý một sự kiện duy nhất khi một hoạt động không đồng bộ hoàn thành hoặc thất bại.

Lưu ý: Có những Promisethư viện ngoài đó hỗ trợ hủy bỏ, nhưng ES6 Promisecho đến nay vẫn chưa có.

Có thể quan sát

An Observablegiống như một Stream(trong nhiều ngôn ngữ) và cho phép vượt qua 0 hoặc nhiều sự kiện trong đó gọi lại được gọi cho mỗi sự kiện.

Thường Observableđược ưa thích hơn Promisebởi vì nó cung cấp các tính năng của Promisevà nhiều hơn nữa. Với Observablenó không thành vấn đề nếu bạn muốn xử lý 0, 1 hoặc nhiều sự kiện. Bạn có thể sử dụng cùng một API trong từng trường hợp.

Observablecũng có lợi thế hơn Promiseđể được hủy bỏ . Nếu kết quả của một yêu cầu HTTP đến một máy chủ hoặc một số hoạt động async đắt khác là không cần thiết nữa, các Subscriptioncủa một Observablephép hủy đăng ký, trong khi một Promisecuối cùng sẽ gọi sự thành công hay thất bại callback ngay cả khi bạn không cần thông báo hoặc kết quả mà nó cung cấp nữa.

Quan sát được cung cấp nhà khai thác như map, forEach, reduce, ... tương tự như một mảng

Ngoài ra còn có các toán tử mạnh như retry(), hoặc replay(), ... thường khá tiện dụng.


180
Vì vậy, có lý do chính đáng để sử dụng Promise thay vì Observable trong trường hợp gọi lại duy nhất hay Observables cũng nên được sử dụng ở đó vì chúng cũng có thể hoạt động theo cách đó? Về cơ bản, đó có phải là cách thực hành tốt để "Quan sát tất cả mọi thứ" hay Promise vẫn có chỗ đứng?
Josh Werts

75
Nếu bạn muốn sử dụng phong cách phản ứng, chỉ cần sử dụng đài quan sát ở mọi nơi. Nếu bạn có thể quan sát chỉ bạn có thể dễ dàng sáng tác. Nếu bạn trộn chúng, nó không còn sạch nữa. Nếu bạn không quan tâm đến phong cách phản ứng, bạn có thể sử dụng lời hứa cho các sự kiện đơn lẻ mà bạn không quan tâm đến việc có thể hủy và quan sát được cho các luồng sự kiện.
Günter Zöchbauer

35
@ GünterZöchbauer Hey - Tôi không có lập luận chống lại Observables hoặc lập trình chức năng. Tôi chỉ đơn giản nói rằng tôi tin rằng mọi người chạy vào Đài quan sát chủ yếu qua http trong NG2 không có lý do thực sự nào để sử dụng Đài quan sát qua Lời hứa để thực hiện các cuộc gọi. Họ không mất gì thực tế bằng cách sử dụng lời hứa. Các toán tử gỡ lỗi và thử lại là không liên quan - bạn có thể gỡ lỗi với ng-debounce và nếu một cuộc gọi dự kiến ​​sẽ thất bại, nói chung, có một vấn đề với mã. Lần duy nhất tôi cần để làm việc với các cuộc gọi thử lại là trong khi truy vấn các API của bên thứ ba không ổn định cho HVT.
VSO

92
Nhưng xin đừng quên điều đó Promise, cùng với async/ awaitlàm cho mã của bạn phẳng trở lại! Trong phần lớn các tình huống và trong các dự án không liên quan đến khoa học tên lửa, không cần phải viết các hàm lồng nhau khủng khiếp đó bằng các chuỗi phương thức phức tạp không cần thiết. Bạn có thể sử dụng async/ awaitngay hôm nay với các bộ chuyển mã, thích TypeScriptvà viết mã phẳng thực sự có thể đọc được của con người mà không cần bất kỳ rxjsmẫu nào. Bạn có thể vẫn sẽ cần rxjsđôi khi trong các tình huống chọn lọc, bởi vì nó thực sự có rất nhiều thứ để cung cấp.
evilkos

15
Câu trả lời này là sai lệch, một quan sát không giống như một luồng nó giống như một hàm trả về một luồng .
Benjamin Gruenbaum

335

Cả hai PromisesObservablescung cấp cho chúng tôi những khái niệm trừu tượng giúp chúng tôi xử lý tính chất không đồng bộ của các ứng dụng của chúng tôi. Sự khác biệt giữa chúng được chỉ ra rõ ràng bởi @ Günter và @Relu.

Vì một đoạn mã có giá trị bằng một ngàn từ, hãy xem qua ví dụ dưới đây để hiểu chúng dễ dàng hơn.

Cảm ơn @Christoph Burgdorf cho bài viết tuyệt vời


Angular sử dụng Rx.js Observables thay vì lời hứa để xử lý HTTP.

Giả sử rằng bạn đang xây dựng một chức năng tìm kiếm sẽ hiển thị ngay kết quả cho bạn khi bạn nhập. Âm thanh quen thuộc nhưng có rất nhiều thử thách đi kèm với nhiệm vụ đó.

  • Chúng tôi không muốn nhấn vào điểm cuối của máy chủ mỗi khi người dùng nhấn phím, nó sẽ tràn ngập chúng với một cơn bão HTTPyêu cầu. Về cơ bản, chúng tôi chỉ muốn nhấn nó một khi người dùng đã ngừng gõ thay vì với mỗi lần nhấn phím.
  • Đừng nhấn điểm cuối tìm kiếm với cùng thông số truy vấn cho các yêu cầu tiếp theo.
  • Đối phó với các phản ứng ngoài đơn đặt hàng. Khi chúng tôi có nhiều yêu cầu trên chuyến bay cùng một lúc, chúng tôi phải tính đến các trường hợp chúng quay lại theo thứ tự không mong muốn. Hãy tưởng tượng đầu tiên chúng ta gõ máy tính , dừng lại, một yêu cầu đi ra ngoài, chúng ta gõ xe , dừng lại, một yêu cầu đi ra ngoài. Bây giờ chúng tôi có hai yêu cầu trong chuyến bay. Thật không may, yêu cầu mang kết quả cho máy tính trở lại sau khi yêu cầu mang kết quả cho xe .

Bản demo sẽ chỉ bao gồm hai tệp: app.tswikipedia-service.ts. Trong một kịch bản thế giới thực, rất có thể chúng ta sẽ phân chia mọi thứ hơn nữa.


Dưới đây là triển khai dựa trên Promise không xử lý bất kỳ trường hợp cạnh được mô tả nào.

wikipedia-service.ts

import { Injectable } from '@angular/core';
import { URLSearchParams, Jsonp } from '@angular/http';

@Injectable()
export class WikipediaService {
  constructor(private jsonp: Jsonp) {}

  search (term: string) {
    var search = new URLSearchParams()
    search.set('action', 'opensearch');
    search.set('search', term);
    search.set('format', 'json');
    return this.jsonp
                .get('http://en.wikipedia.org/w/api.php?callback=JSONP_CALLBACK', { search })
                .toPromise()
                .then((response) => response.json()[1]);
  }
}

Chúng tôi đang tiêm Jsonpdịch vụ để đưa ra GETyêu cầu đối với API Wikipedia với một thuật ngữ tìm kiếm nhất định. Lưu ý rằng chúng tôi gọi toPromiseđể có được từ một Observable<Response>đến a Promise<Response>. Cuối cùng kết thúc với Promise<Array<string>>kiểu trả về của phương thức tìm kiếm của chúng tôi.

app.ts

// check the plnkr for the full list of imports
import {...} from '...';

@Component({
  selector: 'my-app',
  template: `
    <div>
      <h2>Wikipedia Search</h2>
      <input #term type="text" (keyup)="search(term.value)">
      <ul>
        <li *ngFor="let item of items">{{item}}</li>
      </ul>
    </div>
  `
})
export class AppComponent {
  items: Array<string>;

  constructor(private wikipediaService: WikipediaService) {}

  search(term) {
    this.wikipediaService.search(term)
                         .then(items => this.items = items);
  }
}

Không có nhiều bất ngờ ở đây. Chúng tôi tiêm WikipediaServicevà hiển thị chức năng của nó thông qua phương pháp tìm kiếm vào mẫu. Mẫu chỉ đơn giản là liên kết với keyup và các cuộc gọi search(term.value).

Chúng tôi mở ra kết quả của Promise rằng phương thức tìm kiếm của WikipediaService trả về và hiển thị nó dưới dạng một chuỗi các chuỗi đơn giản cho mẫu để chúng tôi có thể *ngForlặp qua nó và xây dựng một danh sách cho chúng tôi.

Xem ví dụ về triển khai dựa trên Promise trên Plunker


Nơi quan sát thực sự tỏa sáng

Hãy thay đổi mã của chúng tôi để không làm hỏng điểm cuối với mỗi lần nhấn phím mà thay vào đó chỉ gửi yêu cầu khi người dùng ngừng gõ trong 400 ms

Để tiết lộ những siêu năng lực như vậy, trước tiên chúng ta cần có một Observable<string>thuật ngữ tìm kiếm mà người dùng nhập vào. Thay vì liên kết thủ công với sự kiện keyup, chúng ta có thể tận dụng formControlchỉ thị của Angular . Để sử dụng chỉ thị này, trước tiên chúng ta cần nhập ReactiveFormsModulemô-đun ứng dụng.

app.ts

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { JsonpModule } from '@angular/http';
import { ReactiveFormsModule } from '@angular/forms';

@NgModule({
  imports: [BrowserModule, JsonpModule, ReactiveFormsModule]
  declarations: [AppComponent],
  bootstrap: [AppComponent]
})
export class AppModule {}

Sau khi nhập, chúng ta có thể sử dụng formControl từ trong mẫu của mình và đặt nó thành tên "hạn".

<input type="text" [formControl]="term"/>

Trong thành phần của chúng tôi, chúng tôi tạo một thể hiện FormControltừ @angular/formvà hiển thị nó dưới dạng một trường dưới thuật ngữ tên trên thành phần của chúng tôi.

Đằng sau hậu trường, thuật ngữ tự động hiển thị một Observable<string>tài sản valueChangesmà chúng ta có thể đăng ký. Bây giờ chúng tôi có một Observable<string>, khắc phục đầu vào của người dùng dễ dàng như gọi debounceTime(400)vào chúng tôi Observable. Điều này sẽ trả về một Observable<string>giá trị mới sẽ chỉ phát ra một giá trị mới khi chưa có giá trị mới trong 400ms.

export class App {
  items: Array<string>;
  term = new FormControl();
  constructor(private wikipediaService: WikipediaService) {
    this.term.valueChanges
              .debounceTime(400)        // wait for 400ms pause in events
              .distinctUntilChanged()   // ignore if next search term is same as previous
              .subscribe(term => this.wikipediaService.search(term).then(items => this.items = items));
  }
}

Sẽ là lãng phí tài nguyên để gửi một yêu cầu khác cho cụm từ tìm kiếm mà ứng dụng của chúng tôi đã hiển thị kết quả. Tất cả những gì chúng ta phải làm để đạt được hành vi mong muốn là gọi cho distinctUntilChangednhà điều hành ngay sau khi chúng ta gọidebounceTime(400)

Xem ví dụ về triển khai quan sát trên Plunker

Để xử lý các phản hồi không theo thứ tự, vui lòng kiểm tra toàn bộ bài viết http: // blog. Dùtram.io / anga / 2016/06/06 / takes-nhược điểm -of-observables-in- angular2.html

Theo như tôi đang sử dụng http trong Angular, tôi đồng ý rằng trong các trường hợp sử dụng thông thường, không có nhiều khác biệt khi sử dụng Observable so với Promise. Không có lợi thế nào thực sự có liên quan ở đây trong thực tế. Hy vọng tôi có thể thấy một số trường hợp sử dụng nâng cao trong tương lai :)


Tìm hiểu thêm


31
Tôi hoàn toàn không mua quyết định biến dịch vụ http thành dựa trên quan sát. Mọi lời giải thích tôi nghe đều dựa trên cùng một ví dụ: Việc tìm kiếm theo thuật ngữ. Nhưng đó là về việc xử lý các sự kiện trình duyệt. Tôi muốn nghe những lợi thế trong việc áp dụng nó khi xử lý các yêu cầu http không đồng bộ.
Alex Pollan

1
Là quyết định tình cờ để tránh các mô hình hỗn hợp?
Alex Pollan

6
@AlexPollan, thực sự có một lời giải thích tốt cho lợi ích của dịch vụ http trả lại một điều có thể quan sát được trên podcast này với Ben Lesh: devchat.tv/js-jabber/ . Cuối cùng, lợi ích chính là bạn có thể hủy bỏ một trường hợp có thể quan sát được và trường hợp sử dụng cho điều này được mô tả trong liên kết ở trên - trong khi có một chút khó khăn - là nếu bạn gọi ra nhiều apis và chỉ quan tâm đến phản hồi đầu tiên, bất kể đó là gì trong số các apis bạn đã gọi trở lại với bạn trước, sau đó bạn có thể hủy các yêu cầu cho người khác.
nikolasleblanc

2
@nikolasleblanc, Tôi khá chắc chắn rằng bạn có thể sử dụng $ q.race () cho điều đó?
jameslouiz

2
@AlexPollan, Ưu điểm là dịch vụ HTTP dựa trên có thể quan sát giúp dễ dàng hủy các yêu cầu HTTP giữa chuyến bay. Điều kiện cuộc đua trong câu trả lời của trungk18 có thể được giải quyết bằng cách hủy đăng ký khỏi HTTP có thể quan sát được trước khi đưa ra yêu cầu tiếp theo. Bản đồ chuyển đổi của RXJS có thể được sử dụng cho các yêu cầu HTTP được kích hoạt bởi một thứ khác có thể quan sát được (ví dụ: valueChanges). Đối với các quan sát HTTP độc lập, bạn có thể hủy đăng ký và đăng ký lại theo cách thủ công.
Stevethemacguy

236

Cả PromiseObservables sẽ giúp chúng tôi làm việc với các chức năng không đồng bộ trong JavaScript. Chúng rất giống nhau trong nhiều trường hợp, tuy nhiên, vẫn có một số khác biệt giữa cả hai, hứa hẹn là các giá trị sẽ giải quyết theo asynchronouscách như các cuộc gọi http . Mặt khác, các đài quan sát xử lý một chuỗi các sự kiện không đồng bộ . Sự khác biệt chính giữa chúng được liệt kê dưới đây:

lời hứa:

  • có một đường ống
  • thường chỉ sử dụng với trả lại dữ liệu không đồng bộ
  • không dễ hủy bỏ

có thể quan sát:

  • có thể hủy bỏ
  • được tái xác định theo bản chất như thử lại và thử lại
  • luồng dữ liệu trong nhiều đường ống
  • có các hoạt động giống như mảng như bản đồ, bộ lọc, vv
  • có thể được tạo từ các nguồn khác như sự kiện
  • chúng là các chức năng, có thể được đăng ký sau này

Ngoài ra, tôi đã tạo hình ảnh đồ họa cho bạn bên dưới để hiển thị sự khác biệt một cách trực quan:

Hình ảnh hứa hẹn và quan sát


4
hứa "không dễ hủy", có thể hủy chúng không?
Pardeep Jain

10
vâng, có một cách để hủy bỏ chúng ... một số người sử dụng thư viện của bên thứ ba hoặc bên thứ ba ... cũng sử dụng thư viện Q trong Angular có nhiều cách để hủy nó ... nhưng như tôi đã nói không tiện lắm
Alireza

Có một đường ống đôi khi có lợi thế, ví dụ. trong APP_INITIALIZER, nếu bạn có nhiều đường ống đôi khi không thể kết thúc hoặc kết thúc nhiều lần.
Windmaomao

6
hủy bỏ a Promiselà cách sai lầm để suy nghĩ về cách hứa hẹn. Các Promise's trách nhiệm nó chỉ để xử lý thành công hay thất bại trong một cách tương thích async .. Nếu bạn muốn hủy bỏ một http request bạn hủy theo yêu cầu, không phải là lời hứa, và làm cho kết quả hủy hoặc thực hiện hoặc từ chối lời hứa. jsfiddle.net/greggman/ea0yhd4p
gman

2
@gman Chính xác. Lời hứa chỉ đơn giản là đại diện cho một số giá trị trong tương lai . Nó không đại diện cho hoạt động tạo ra giá trị . Bạn không thể hủy bỏ một giá trị. Bạn không thể thử lại một giá trị. Đó chỉ là một giá trị. Nó có thể có hoặc không có mặt , và nó có thể không bao giờ tồn tại vì một ngoại lệ xảy ra, nhưng đó là nó.
Yona Appletree

75

Hứa

  1. Định nghĩa: Giúp bạn chạy các chức năng không đồng bộ và sử dụng các giá trị trả về của chúng (hoặc ngoại lệ) nhưng chỉ một lần khi được thực thi.
  2. Không lười biếng
  3. Không thể hủy bỏ (Có những thư viện Promise ngoài đó hỗ trợ hủy bỏ, nhưng ES6 Promise không tồn tại cho đến nay). Hai quyết định có thể là
    • Từ chối
    • Giải quyết
  4. Không thể được thử lại (Các lời hứa nên có quyền truy cập vào chức năng ban đầu đã trả lại lời hứa sẽ có khả năng thử lại, đây là một thực tiễn tồi)

Đài quan sát

  1. Định nghĩa: Giúp bạn chạy các hàm không đồng bộ và sử dụng các giá trị trả về của chúng theo một chuỗi liên tục ( nhiều lần ) khi được thực thi.
  2. Theo mặc định, nó là Lazy vì nó phát ra các giá trị khi thời gian tiến triển.
  3. Có rất nhiều toán tử giúp đơn giản hóa nỗ lực mã hóa.
  4. Một toán tử thử lại có thể được sử dụng để thử lại bất cứ khi nào cần thiết, ngoài ra nếu chúng ta cần thử lại có thể quan sát được dựa trên một số điều kiện thì có thể sử dụng lại.

    Lưu ý : Danh sách các toán tử cùng với sơ đồ tương tác của họ có sẵn tại RxMarbled.com


67

Có một nhược điểm của Observables bị thiếu trong các câu trả lời. Hứa hẹn cho phép sử dụng các chức năng async / await ES7. Với chúng, bạn có thể viết mã không đồng bộ giống như nó sẽ là một cuộc gọi hàm đồng bộ, vì vậy bạn không cần gọi lại nữa. Khả năng duy nhất để Observables thực hiện điều này là chuyển đổi chúng thành Promise. Nhưng khi bạn chuyển đổi chúng thành Lời hứa, bạn chỉ có thể có một giá trị trả lại:

async function getData(){
    const data = await observable.first().toPromise();
    //do stuff with 'data' (no callback function needed)
}

Đọc thêm: Làm thế nào tôi có thể 'chờ đợi' trên Rx Observable?


21
Cũng ngạc nhiên tại sao không ai chỉ ra lợi ích giết người này của Promise - sự đơn giản và minh bạch nhờ async / await. Tôi chuyển sang Promise chỉ vì khả năng viết mã phẳng. Logic kinh doanh đơn giản và mã tương tác UI không nên trông giống như khoa học tên lửa và bị ô nhiễm bởi địa ngục của các phần mở rộng phản ứng lồng nhau. Ngoài ra, async / await không chỉ trong tương lai, bạn có thể sử dụng nó trong các ứng dụng sản xuất công cộng hiện đang sử dụng bộ chuyển mã. Tôi sử dụng TypeScript 2.3 và nó thật tuyệt vời, giống như một ngôn ngữ thực sự.
evilkos

Đẹp, nhưng suy nghĩ theo cách phản ứng và tất cả với RxOperators có lẽ đây không phải là một tính năng giết người
JorgeTovar

37

Cả Promise và Observables đều chỉ xử lý cuộc gọi không đồng bộ.

Dưới đây là sự khác biệt giữa chúng:

Có thể quan sát

  1. Phát ra nhiều giá trị trong một khoảng thời gian
  2. Không được gọi cho đến khi chúng tôi đăng ký vào Đài quan sát
  3. Có thể bị hủy bằng cách sử dụng phương thức hủy đăng ký ()
  4. Cung cấp bản đồ, forEach, bộ lọc, thu nhỏ, thử lại và thử lại khi các toán tử

Lời hứa

  1. Mỗi lần chỉ phát ra một giá trị

  2. Gọi các dịch vụ mà không có .then và .catch

  3. Không thể bị hủy

  4. Không cung cấp bất kỳ nhà khai thác


2
Chính xác thì ý của bạn là gì khi lời hứa chỉ phát ra một giá trị duy nhất, trong khi có thể quan sát được phát ra nhiều
Abel

2
Một lời hứa hoàn toàn không phát ra một giá trị - một lời hứa một giá trị theo thời gian. Một lời hứa đa chiều có giá trị cho nhiều người đăng ký - một khi bạn giữ lời hứa bạn đã có một giá trị. Một quan sát giống như một chức năng , đăng ký vào nó gọi hành động.
Benjamin Gruenbaum

1
@BenjaminGruenbaum Tuy nhiên, tôi không nhận được ý nghĩa của nhiều người đăng ký, bạn có thể vui lòng cung cấp một liên kết hoặc ví dụ. Cảm ơn
Deepak Patidar

2
obsable1.subscribe (thuê bao1), obsable1.subscribe (thuê bao2) - điều này gọi hàm nhiều lần.
Benjamin Gruenbaum

2
Vui lòng chỉnh sửa bài viết của bạn và hiển thị văn bản thực tế thay vì ảnh chụp màn hình. Những người khác không thể sao chép và dán từ hình ảnh của bạn và cũng không thể giúp bạn sửa nhiều lỗi ngữ pháp. Xem ở đây để biết chi tiết. Cảm ơn bạn.
Pang

26

Mặc dù câu trả lời này là muộn, tôi đã tóm tắt những khác biệt dưới đây,

Có thể quan sát:

  1. Có thể quan sát chỉ là một functionmất an observervà trả lại một function Observer: an object with next, error.
  2. Người quan sát cho phép subscribe/unsubscribeluồng dữ liệu của nó, phát ra giá trị tiếp theo cho người quan sát, notifyngười quan sát errorsvà thông báo cho người quan sát vềstream completion
  3. Observer cung cấp a function to handle next value, lỗi và kết thúc luồng (sự kiện ui, phản hồi http, dữ liệu với ổ cắm web).
  4. Làm việc multiple valuestheo thời gian
  5. Đó là cancel-able/retry-ablevà hỗ trợ các nhà khai thác như map,filter,reducevv
  6. Tạo một Observable có thể - Observable.create()trả về Có thể quan sát có thể gọi các phương thức trên - Observer Observable.from()- chuyển đổi một mảng hoặc lặp lại thành - Observable Observable.fromEvent()- chuyển đổi một sự kiện thành Observable - Observable.fromPromise()- chuyển đổi một Promise thành Observable - Observable.range()- trả về một chuỗi các số nguyên trong phạm vi cụ thể

Hứa :

  1. Một lời hứa đại diện cho một nhiệm vụ sẽ hoàn thành trong tương lai;

  2. Hứa sẽ trở thành resolved by a value;

  3. Lời hứa bị từ chối bởi các ngoại lệ;

  4. Không cancellablevà nó trở lạia single value

  5. Một lời hứa phơi bày một chức năng (then)

    -then trả lại một cái mới promise;

    -tất cả cho attachmentđiều đó sẽ được thực hiện dựa trên state;

    - handlersguaranteedđể thực hiện trong order attached;


20

Tôi vừa giải quyết một vấn đề trong đó Promise là giải pháp tốt nhất và tôi chia sẻ nó ở đây cho bất kỳ ai vấp phải câu hỏi này trong trường hợp nó hữu ích (đây chính xác là câu trả lời tôi đang tìm kiếm trước đó):

Trong một dự án Angular2, tôi có một dịch vụ lấy một số tham số và trả về một danh sách giá trị để điền vào các menu thả xuống trên một biểu mẫu. Khi thành phần biểu mẫu khởi tạo, tôi cần gọi cùng một dịch vụ nhiều lần với các tham số khác nhau để xác định một số menu thả xuống khác nhau, tuy nhiên nếu tôi chỉ xếp hàng tất cả các biến để gọi dịch vụ, chỉ có một biến cuối cùng thành công và lỗi còn lại ngoài. Dịch vụ tìm nạp từ cơ sở dữ liệu chỉ có thể xử lý một yêu cầu tại một thời điểm.

Cách duy nhất để điền thành công tất cả các biến menu thả xuống là gọi dịch vụ theo cách ngăn yêu cầu mới được xử lý cho đến khi yêu cầu cuối cùng kết thúc và cơ chế Promise / .then đã giải quyết vấn đề một cách độc đáo.

  fetchValueList(listCode): Promise<any> {
      return this.dataSvc.getValueList(listCode, this.stateSvc.currentContext, this.stateSvc.currentLanguageCode)
          .map(response => response.json())
          .toPromise();
  }

  initializeDropDowns() {
      this.fetchValueList('First-Val-List')
          .then(data => {
              this.firstValList = data;
              return this.fetchValueList('Second-Val-List')
          }).then(data => {
              this.secondValList = data;
              return this.fetchValueList('Third-Val-List')
          }).then(data => {
              this.thirdValList = data;
          })  }

Tôi đã định nghĩa các hàm trong thành phần, và sau đó được gọi là initizeDropDowns () trong ngOnInit.

Hàm fetchValueList trả về một Promise, vì vậy lệnh gọi đầu tiên sẽ chuyển listCode đầu tiên và khi Promise giải quyết, giá trị trả về nằm trong biến dữ liệu trong khối .then nơi chúng ta có thể gán nó cho biến this.firstValList. Vì hàm đã trả về dữ liệu, chúng tôi biết dịch vụ đã kết thúc và sẽ an toàn khi gọi lại với listCode thứ hai, giá trị trả về nằm trong biến dữ liệu trong khối .then tiếp theo và chúng tôi gán nó cho biến this.secondValList.

Chúng ta có thể xâu chuỗi số này nhiều lần theo yêu cầu để điền vào tất cả các biến và trên khối mã cuối cùng, chúng ta chỉ cần bỏ qua câu lệnh return và khối kết thúc.

Đây là trường hợp sử dụng rất cụ thể khi chúng tôi có một dịch vụ cần được gọi nhiều lần khi thành phần khởi tạo và khi dịch vụ phải hoàn thành tìm nạp và trả về giá trị trước khi có thể gọi lại, nhưng trong trường hợp này, phương pháp Promise / .then là lý tưởng.


3
Điều này chắc chắn cũng có thể với các vật quan sát (bậc cao hơn). Ví dụ, bạn có thể sử dụng scan()để xây dựng một luồng các quan sát liên tiếp. Tuy nhiên, cách tiếp cận của bạn có thể rõ ràng hơn và dễ hiểu hơn.
lex82

1
Bạn có thể thay thế "sau đó" bằng "switchMap" và thực hiện chính xác điều tương tự w / obsables.
Bác sĩ C. Hilarius

1
Vấn đề với switchMap, theo tôi hiểu, là nó sẽ bắt đầu song song tất cả các yêu cầu và đợi cho đến khi tất cả chúng trả về, sau đó trả lại các giá trị cho hàm gọi trong khi trong tình huống của tôi, tôi có một máy chủ duy nhất mà tôi không thể gọi song song nhiều lần (vì máy chủ sẽ bỏ các yêu cầu chưa hoàn thành khi có yêu cầu mới), vì vậy tôi phải đảm bảo mỗi cuộc gọi đến dịch vụ cơ sở dữ liệu đã hoàn thành trước khi bắt đầu một cuộc gọi mới và Promise / sau đó dường như là tốt nhất và có lẽ chỉ có cách để giải quyết điều đó
Stephen R. Smith

1
Tại sao bạn không sử dụng mergMap chuỗi? Theo như tôi hiểu mã của bạn, thì mã này khá đơn giản và thực hiện công việc tốt như ví dụ của bạn. @ StephenR.Smith
Ore

1
@Ore Bạn có thể thêm một ví dụ mã về việc giải quyết vấn đề tương tự như một câu trả lời khác không? Sẽ là một tài liệu tham khảo tốt và có thể là một cơ hội tái cấu trúc tốt trong tương lai. Yêu cầu là bất cứ mã nào không thể gọi song song dịch vụ phụ trợ, nó phải gọi, đợi giá trị trả về và gọi lại.
Stephen R. Smith

20

Tôi tin rằng tất cả các câu trả lời khác sẽ xóa tan nghi ngờ của bạn. Tuy nhiên, tôi chỉ muốn thêm rằng các đài quan sát được dựa trên lập trình chức năng và tôi thấy rất hữu ích các chức năng đi kèm với nó như bản đồ, bản đồ phẳng, thu nhỏ, zip. Tính nhất quán mà web đạt được đặc biệt là khi nó phụ thuộc vào các yêu cầu API là một cải tiến tàn bạo.

Tôi thực sự khuyên bạn nên tài liệu này , vì nó là tài liệu chính thức của ReactiveX và tôi thấy nó là tài liệu rõ ràng nhất hiện có.

Nếu bạn muốn quan sát, tôi sẽ đề xuất bài đăng gồm 3 phần này: http://blog.danlew.net/2014/09/15/grokking-rxjava-part-1/

Mặc dù nó có nghĩa là cho RxJava, các khái niệm là như nhau, và nó thực sự được giải thích tốt. Trong tài liệu ReactiveX, bạn có các giá trị tương đương cho từng chức năng. Bạn phải tìm RxJS.


18

Lời hứa:

  • Cung cấp một giá trị tương lai duy nhất;
  • Không lười biếng;
  • Không thể hủy bỏ;

Có thể quan sát:

  • Phát ra nhiều giá trị theo thời gian;
  • Lười biếng;
  • Hủy bỏ;
  • Hỗ trợ bản đồ, bộ lọc, giảm và các toán tử tương tự

Bạn có thể sử dụng lời hứa thay vì có thể quan sát khi gọi HTTP trong Angular nếu muốn.


16

Tổng quat:

  • Cả Promise và Observables đều giúp chúng tôi xử lý các hoạt động không đồng bộ. Họ có thể gọi các cuộc gọi lại nhất định khi các hoạt động không đồng bộ này được thực hiện.
  • Lời hứa chỉ có thể xử lý một sự kiện, Đài quan sát dành cho các luồng sự kiện theo thời gian
  • Lời hứa không thể bị hủy bỏ khi chúng đang chờ xử lý
  • Dữ liệu quan sát phát ra có thể được chuyển đổi bằng cách sử dụng các toán tử

Bạn luôn có thể sử dụng một thiết bị quan sát để xử lý hành vi không đồng bộ vì một thiết bị quan sát có tất cả các chức năng mà một lời hứa cung cấp (+ thêm). Tuy nhiên, đôi khi chức năng bổ sung này mà Observables cung cấp không cần thiết. Sau đó, sẽ là thêm chi phí để nhập một thư viện cho nó để sử dụng chúng.

Khi nào nên sử dụng Lời hứa:

Sử dụng lời hứa khi bạn có một hoạt động không đồng bộ duy nhất mà bạn muốn xử lý kết quả. Ví dụ:

var promise = new Promise((resolve, reject) => {
  // do something once, possibly async
  // code inside the Promise constructor callback is getting executed synchronously

  if (/* everything turned out fine */) {
    resolve("Stuff worked!");
  }
  else {
    reject(Error("It broke"));
  }
});

//after the promise is resolved or rejected we can call .then or .catch method on it

promise.then((val) => console.log(val))      // logs the resolve argument
       .catch((val) => console.log(val));    // logs the reject argument

Vì vậy, một lời hứa thực thi một số mã trong đó nó giải quyết hoặc từ chối. Nếu giải quyết hoặc từ chối được gọi là lời hứa sẽ chuyển từ trạng thái chờ xử lý sang trạng thái được giải quyết hoặc bị từ chối . Khi trạng thái lời hứa được giải quyết, then()phương thức được gọi. Khi trạng thái lời hứa bị từ chối, catch()phương thức được gọi.

Khi nào nên sử dụng Đài quan sát:

Sử dụng Đài quan sát khi có luồng (dữ liệu) theo thời gian mà bạn cần xử lý. Luồng là một chuỗi các yếu tố dữ liệu đang được cung cấp theo thời gian . Ví dụ về các luồng là:

  1. Sự kiện người dùng, ví dụ nhấp chuột hoặc sự kiện keyup. Người dùng tạo các sự kiện (dữ liệu) theo thời gian.
  2. Websockets, sau khi máy khách tạo kết nối WebSocket đến máy chủ, nó sẽ đẩy dữ liệu theo thời gian.

Trong Observable, chính nó được chỉ định khi sự kiện tiếp theo xảy ra, khi xảy ra lỗi hoặc khi Observable hoàn thành . Sau đó, chúng tôi có thể đăng ký để có thể quan sát được, điều này kích hoạt nó và trong đăng ký này, chúng tôi có thể vượt qua 3 cuộc gọi lại (không phải luôn luôn vượt qua tất cả). Một cuộc gọi lại được thực hiện để thành công, một cuộc gọi lại cho lỗi và một cuộc gọi lại để hoàn thành. Ví dụ:

const observable = Rx.Observable.create(observer => {
  // create a single value and complete
  observer.onNext(1);
  observer.onCompleted();
});

source.subscribe(
  x => console.log('onNext: %s', x),   //  success callback
  e => console.log('onError: %s', e),  //  error callback
  () => console.log('onCompleted')     //  completion callback
 );

// first we log: onNext: 1
//  then we log: onCompleted

Khi tạo một quan sát được, nó đòi hỏi một hàm gọi lại cung cấp cho người quan sát làm đối số. Trên quan sát này, bạn có thể gọi tới onNext, onCompleted, onError. Sau đó, khi Observable được đăng ký, nó sẽ gọi các cuộc gọi lại tương ứng được chuyển vào đăng ký.


9

Hứa hẹn - Cung cấp một giá trị tương lai duy nhất. Không lười biếng. Không thể hủy bỏ. Nó sẽ từ chối hoặc giải quyết.

Có thể quan sát - Cung cấp nhiều giá trị trong tương lai. Lười biếng . Hủy bỏ có thể. Nó cung cấp các phương pháp khác sống bản đồ, lọc, giảm.


8

Hứa hẹn tương tự quan sát đầu tiên

  1. Cả hai được sử dụng để xử lý mã async.
  2. Hãy tìm ví dụ về lời hứa. Hàm tạo hứa hẹn chuyển một hàm tham chiếu giải quyết sẽ được gọi khi nó được gọi với một số giá trị khi hoàn thành một số tác vụ không đồng bộ.

const promise = new Promise(resolve => {
  setTimeout(() => {
    resolve("Hello from a Promise!");
  }, 2000);
});

promise.then(value => console.log(value));

  1. Ví dụ quan sát bây giờ. Ở đây chúng tôi cũng chuyển một chức năng để có thể quan sát, một người quan sát để xử lý tác vụ không đồng bộ. Không giống như giải quyết trong lời hứa, nó có phương thức sau và đăng ký thay thế sau đó.

  2. Vì vậy, cả hai xử lý các nhiệm vụ không đồng bộ. Bây giờ hãy xem sự khác biệt.


const observable = new Observable(observer => {
  setTimeout(() => {
    observer.next('Hello from a Observable!');
  }, 2000);
});

observable.subscribe(value => console.log(value));

Promise vs sự khác biệt quan sát

Lời hứa

  1. Nó giải quyết hoặc từ chối một giá trị duy nhất và có thể xử lý một tác vụ không đồng bộ giá trị duy nhất tại một thời điểm.
  2. Một lời hứa một khi đã giải quyết giá trị async mà nó hoàn thành, không thể sử dụng được nữa. Chỉ cần sử dụng một lần và ở đây nó bị thiếu.
  3. Không thể hủy bỏ
  4. Không hỗ trợ rxjs cho các nhà khai thác.

Có thể quan sát

  1. khả năng phát ra nhiều giá trị không đồng bộ.
  2. Được sử dụng để xử lý luồng sự kiện hoặc giá trị. Hãy xem xét bạn có một mảng gồm nhiều nhiệm vụ hoặc giá trị và bạn muốn mỗi khi giá trị được chèn vào thì nó sẽ được xử lý tự động. Bất cứ khi nào bạn đẩy một giá trị vào mảng này, tất cả những người đăng ký của nó sẽ tự động nhận được giá trị mới nhất.
  3. Các thiết bị quan sát rất hữu ích để quan sát các thay đổi đầu vào, khoảng thời gian lặp lại, giá trị quảng bá đến tất cả các thành phần con, thông báo đẩy ổ cắm web, v.v.
  4. Có thể được hủy bằng phương pháp hủy đăng ký bất cứ lúc nào.
  5. Một phần tốt nữa cuối cùng hứa hẹn có hỗ trợ cho các nhà khai thác rxjs. Bạn có nhiều toán tử đường ống chủ yếu là ánh xạ, bộ lọc, switchMap, kết hợpLatest, v.v. để chuyển đổi dữ liệu quan sát được trước khi đăng ký.

nhập mô tả hình ảnh ở đây



6

Cả Promise và Observables đều giúp chúng tôi xử lý các hoạt động không đồng bộ. Họ có thể gọi các cuộc gọi lại nhất định khi các hoạt động không đồng bộ này được thực hiện.

Angular sử dụng các thiết bị quan sát từ RxJS thay vì lời hứa để xử lý HTTP

Below are some important differences in promises & Observables.

sự khác biệt giữa Promise và Observables


1
Dữ liệu được lập bảng có vẻ không chính xác, tiêu đề nên được hoán đổi
Derrick.X

1
Vui lòng chỉnh sửa bài đăng của bạn và hiển thị nội dung thực tế dưới dạng văn bản thay vì ảnh chụp màn hình. Những người khác không thể sao chép và dán từ hình ảnh của bạn. Xem ở đây để biết chi tiết. Cảm ơn bạn.
Pang

6

Lời hứa phát ra một sự kiện duy nhất khi một hoạt động không đồng bộ kết thúc hoặc thất bại.

Một Observable giống như một Luồng (bằng nhiều ngôn ngữ) và cho phép vượt qua ít nhất 0 hoặc nhiều sự kiện trong đó yêu cầu gọi lại cho mọi sự kiện.

Thường xuyên quan sát được ưa thích hơn Promise vì nó mang lại những điểm nổi bật của Promise và hơn thế nữa. Với Observable, không cần thiết nếu bạn cần xử lý 0, 1 hoặc các sự kiện khác nhau. Bạn có thể sử dụng API tương tự cho từng trường hợp.

Promise: lời hứa phát ra một giá trị duy nhất

Ví dụ:

const numberPromise = new Promise((resolve) => {
    resolve(5);
    resolve(10);
});

numberPromise.then(value => console.log(value));
// still prints only 5

Có thể quan sát: Phát ra nhiều giá trị trong một khoảng thời gian

Ví dụ:

  const numberObservable = new Observable((observer) => {
        observer.next(5);
        observer.next(10);
    });

numberObservable.subscribe(value => console.log(value));
// prints 5 and 10

chúng ta có thể nghĩ về một luồng có thể quan sát giống như một luồng phát ra nhiều giá trị trong một khoảng thời gian và cùng một hàm gọi lại được gọi cho mỗi mục được phát ra để có thể quan sát được, chúng ta có thể sử dụng cùng một API để xử lý dữ liệu không đồng bộ. liệu dữ liệu đó được truyền dưới dạng một giá trị hay nhiều giá trị trong một khoảng thời gian.

Lời hứa:

  • Một lời hứa không lười biếng
  • Một lời hứa không thể bị hủy bỏ

Có thể quan sát:

  • Có thể quan sát là Lười. "Có thể quan sát" là chậm. Nó không được gọi cho đến khi chúng tôi đăng ký nó.
  • Có thể hủy bỏ một Observable bằng cách sử dụng phương thức hủy đăng ký ()
  • Một bổ sung Observable cung cấp nhiều toán tử mạnh như map, foreach, bộ lọc, rút ​​gọn, thử lại, thử lại, v.v.

Lời hứa góc cạnh vs Đài quan sát


5

Promise phát ra một giá trị trong khi Observable phát ra nhiều giá trị. Vì vậy, trong khi xử lý một yêu cầu HTTP, Promise có thể quản lý một phản hồi cho cùng một yêu cầu, nhưng nếu có nhiều phản hồi cho cùng một yêu cầu thì chúng ta phải sử dụng Observable. Có, Observable có thể xử lý nhiều phản hồi cho cùng một yêu cầu.

Lời hứa

const promise = new Promise((data) =>
{ data(1);
  data(2);
  data(3); })
.then(element => console.log(‘Promise ‘ + element));

Đầu ra

Promise 1

Có thể quan sát

const observable = new Observable((data) => {
data.next(1);
data.next(2);
data.next(3);
}).subscribe(element => console.log('Observable ' + element));

Đầu ra

Observable 1
Observable 2
Observable 3

3

Dưới đây là một số khác biệt quan trọng trong lời hứa và quan sát.

Lời hứa

  • Chỉ phát ra một giá trị
  • Không thể hủy bỏ
  • Không thể chia sẻ
  • Luôn không đồng bộ

Có thể quan sát

  • Phát ra nhiều giá trị
  • Chỉ thực hiện khi nó được gọi hoặc ai đó đang đăng ký
  • Có thể hủy bỏ
  • Có thể được chia sẻ và đăng ký giá trị được chia sẻ bởi nhiều người đăng ký. Và tất cả các thuê bao sẽ thực hiện tại một thời điểm duy nhất.
  • có thể không đồng bộ

Để hiểu rõ hơn, hãy tham khảo https://stackblitz.com/edit/observable-vs-promises


3

Tôi thấy rất nhiều người sử dụng đối số mà Observable là "có thể hủy được" nhưng việc tầm thường là "không thể hủy bỏ"

function cancellablePromise(body) {
  let resolve, reject;
  const promise = new Promise((res, rej) => {
    resolve = res; reject = rej;
    body(resolve, reject)
  })
  promise.resolve = resolve;
  promise.reject = reject;
  return promise
}

// Example 1: Reject a promise prematurely
const p1 = cancellablePromise((resolve, reject) => {
  setTimeout(() => resolve('10', 100))
})

p1.then(value => alert(value)).catch(err => console.error(err))
p1.reject(new Error('denied')) // expect an error in the console

// Example: Resolve a promise prematurely
const p2 = cancellablePromise((resolve, reject) => {
  setTimeout(() => resolve('blop'), 100)
})

p2.then(value => alert(value)).catch(err => console.error(err))
p2.resolve(200) // expect an alert with 200


2

Câu trả lời ngắn :

Có thể quan sáttốt hơn , nó có tất cả các tính năng Promise cộng với các tính năng bổ sung.


Câu trả lời dài:

Hứa hẹn:

  • Sử dụng một lần "Trả lại dữ liệu một lần"
  • Không hủy
  • Một người nghe
  • Không có socket Hỗ trợ một Listener

Có thể quan sát:

  • Trả về dữ liệu nhiều lần khi dữ liệu thay đổi
  • Hỗ trợ hủy bỏ
  • Hỗ trợ ổ cắm
  • Hỗ trợ nhiều người nghe và thông báo cho họ khi thay đổi dữ liệu
  • Hỗ trợ bản đồ, bộ lọc, giảm

Tôi không nghĩ bạn có thể nói Observables là khách quan hơn. Có một số nhược điểm đối với Đài quan sát được ghi nhận trong các câu trả lời khác nhau ở đây. Những cái nổi bật với tôi là độ phức tạp của Observable và chúng không hoạt động trực tiếp với await / async. Cá nhân tôi thấy chúng rất khó để làm việc vì bạn không thể xác định hành vi của một Người quan sát khi sử dụng nó - bạn phải xem mã đã tạo ra nó. Trong khi đó với một lời hứa, bạn sẽ biết chính xác cách họ làm việc, luôn luôn. Ví dụ: đôi khi đăng ký vào Đài quan sát có tác dụng phụ (ví dụ: yêu cầu http), nhưng đôi khi thì không.
Yona Appletree

Đối với góc, nó phụ thuộc vào trường hợp của bạn. trong hầu hết các trường hợp, chúng tôi sẽ làm việc với các dịch vụ và một số dữ liệu sẽ ảnh hưởng đến các địa điểm khác nhau, ổ cắm, hủy, bản đồ, bộ lọc và giảm. Vì vậy, nó sẽ tốt hơn trong những trường hợp như lời hứa không hỗ trợ họ. vì vậy một lần nữa nó phụ thuộc vào trường hợp của bạn
Amr Ibrahim

2

Mặc dù câu trả lời được chấp nhận là tốt nói chung, tôi không nghĩ rằng nó nhấn mạnh rằng khi giao dịch với các Thành phần góc, bạn hầu như luôn muốn sử dụng một Đài quan sát vì nó hỗ trợ hủy bỏ. Lời hứa không thể bị hủy và sẽ giải quyết ngay cả khi thành phần của bạn bị hủy. Angular có xu hướng tha thứ cho đến khi nó không.

Ví dụ: mọi phát hiện thay đổi thủ công trên một thành phần bị phá hủy sẽ gây ra ngoại lệ:

ngOnInit() {
  // promise api
  this.service.getData().then(d => {
     this.data = d;
     this.changeDetectorRef.detectChanges();
  });

  // observable api
  this.service.getData().pipe(takeUntil(this.unsubscribe)).subscribe((d) => {
     this.data = d;
     this.changeDetectorRef.detectChanges();
  });
}

Nếu thành phần của bạn bị hủy trước khi lời hứa được giải quyết, bạn sẽ gặp attempt to use destroyed viewlỗi khi lời hứa được giải quyết.

Ngoài ra, nếu bạn sử dụng các thiết bị quan sát với mẫu TakeUntil , thì ngay khi thành phần của bạn bị hủy, đăng ký sẽ bị hủy.

Đây là một ví dụ giả định nhưng việc thực thi mã cho một thành phần bị phá hủy có thể sẽ dẫn đến lỗi. Trừ khi bạn thực sự muốn làm điều đó vì một số lý do: p


2

Một cái gì đó tôi gặp phải điều đó không rõ ràng từ lần đọc hướng dẫn đầu tiên và tài liệu là ý tưởng về đa hướng hóa.

Hãy chắc chắn rằng bạn biết rằng theo mặc định, nhiều đăng ký sẽ kích hoạt nhiều lần thực thi trong một Đài quan sát. Nhiều đăng ký cho một cuộc gọi HTTP có thể quan sát được sẽ kích hoạt nhiều cuộc gọi HTTP giống nhau trừ khi bạn .share()(bật đa tuyến).

Một lời hứa buộc bạn phải giải quyết một vấn đề tại một thời điểm, mở dữ liệu của nó, xử lý các trường hợp ngoại lệ, hỗ trợ ngôn ngữ cho những thứ hay ho như async / await, và là những barebones khá khác.

Một chiếc Observable có rất nhiều chuông và còi, nhưng bạn cần hiểu sức mạnh mà bạn đang làm việc hoặc nó có thể bị lạm dụng.


2

Lời hứa:

Trình xử lý sự kiện Async - Đối tượng Promise biểu thị sự hoàn thành cuối cùng (hoặc thất bại) của một hoạt động không đồng bộ và giá trị kết quả của nó.

Cú pháp: Promise mới (người thực thi);

Ví dụ:

var promise_eg = new Promise(function(resolve, reject) {
  setTimeout(function() {
    resolve('foo');
  }, 300);
});

promise_eg.then(function(value) {
  console.log(value);
  // expected output: "foo"
});

console.log(promise_eg);

nhập mô tả hình ảnh ở đây

Về lời hứa: Nó có một đường ống vì vậy, nó sẽ chỉ trả về giá trị một lần khi được gọi. Trình xử lý một chiều của nó vì vậy một khi đã gọi bạn có thể không thể hủy. cú pháp hữu ích bạn có thể chơi xung quanh, khi ()sau đó ()

Đài quan sát:

Đài quan sát là bộ sưu tập lười biếng của nhiều giá trị theo thời gian. nó thực sự là một cách tiếp cận tuyệt vời cho các hoạt động không đồng bộ. nó có thể được thực hiện với rxjs có hỗ trợ đa nền tảng có thể sử dụng với góc / phản ứng, v.v.

nó hoạt động như luồng lót. có thể là nhiều đường ống. vì vậy một khi được xác định, bạn có thể đăng ký để nhận kết quả trả lại ở nhiều nơi.

Cú pháp: import * as Rx from "@reactivex/rxjs"; để init:

Rx.Observable.fromEvent(button, "click"),
Rx.Subject()

Vân vân

để đăng ký: RxLogger.getInstance();

Ví dụ:

import { range } from 'rxjs';
import { map, filter } from 'rxjs/operators';

range(1, 200).pipe(
  filter(x => x % 2 === 1),
  map(x => x + x)
).subscribe(x => console.log(x));

vì nó hỗ trợ nhiều đường ống dẫn, bạn có thể đăng ký kết quả ở vị trí khác nhau, nhập mô tả hình ảnh ở đây nó có nhiều khả năng hơn so với lời hứa.

Cách sử dụng: nó có nhiều khả năng nhưmap, filter, pipe, map, concatMap etc


2

Sự khác biệt cơ bản giữa có thể quan sát và lời hứa là:

nhập mô tả hình ảnh ở đây


2
Vui lòng chỉnh sửa bài đăng của bạn và hiển thị nội dung thực tế dưới dạng văn bản thay vì ảnh chụp màn hình. Những người khác không thể sao chép và dán từ hình ảnh của bạn. Xem ở đây để biết chi tiết. Cảm ơn bạn.
Pang

1

Quan sát thường được so sánh với lời hứa. Dưới đây là một số khác biệt chính:

Đài quan sát là khai báo; tính toán không bắt đầu cho đến khi đăng ký. Hứa sẽ thực hiện ngay lập tức khi sáng tạo. Điều này làm cho các quan sát hữu ích để xác định công thức nấu ăn có thể được chạy bất cứ khi nào bạn cần kết quả.

Đài quan sát cung cấp nhiều giá trị. Hứa sẽ cung cấp một. Điều này làm cho các quan sát hữu ích để có được nhiều giá trị theo thời gian.

Quan sát phân biệt giữa chuỗi và thuê bao. Hứa chỉ có mệnh đề .then (). Điều này làm cho các thiết bị quan sát trở nên hữu ích để tạo các công thức biến đổi phức tạp được sử dụng bởi các phần khác của hệ thống, mà không khiến công việc được thực thi.

Observables đăng ký () chịu trách nhiệm xử lý lỗi. Hứa hẹn đẩy lỗi cho trẻ hứa. Điều này làm cho các thiết bị quan sát hữu ích cho việc xử lý lỗi tập trung và có thể dự đoán được.

Đó là sự khác biệt đơn giản nhất mà bạn có thể tìm thấy trên các tài liệu ANGULAR.IO. phần còn lại câu trả lời được đưa ra bởi hầu hết là chính xác tại vị trí của nó


1
  1. Hứa hẹn chỉ tập trung cho các giá trị đơn lẻ hoặc độ phân giải, các vật thể quan sát là luồng dữ liệu.

  2. Đài quan sát có thể bị hủy nhưng lời hứa không thể bị hủy.

Người ít được biết đến nhất, ít nhất với tôi là

  1. Lời hứa luôn có bản chất không đồng bộ, nhưng các vật thể quan sát có thể vừa đồng bộ vừa không đồng bộ.

0
  1. một lời hứa là háo hức, trong khi một người quan sát là lười biếng,
  2. một Promise luôn không đồng bộ, trong khi một Observable có thể là đồng bộ hoặc không đồng bộ,
  3. một Promise có thể cung cấp một giá trị duy nhất, trong khi một Observable là một
    luồng các giá trị (từ 0 đến nhiều giá trị),
  4. bạn có thể áp dụng các toán tử RxJS cho một Đài quan sát để có được một luồng tùy chỉnh mới.

-1

Các quan sát và lời hứa đang giúp chúng tôi làm việc với các chức năng không đồng bộ trong JavaScript / bản thảo. Chúng rất giống nhau trong nhiều trường hợp, tuy nhiên, vẫn có một số khác biệt giữa chúng.

nhập mô tả hình ảnh ở đây


1
Vui lòng chỉnh sửa bài viết của bạn và hiển thị văn bản thực tế thay vì ảnh chụp màn hình. Những người khác không thể sao chép và dán từ hình ảnh của bạn. Xem ở đây để biết chi tiết. Cảm ơn bạn.
Pang

Ngoại trừ đó không phải là mã mà là thông tin đơn giản, vì vậy tôi nghĩ sẽ ổn khi đăng nó dưới dạng hình ảnh
Alator

1
dừng sao chép dán từ video youtube của Kudvenkat. Downvote từ tôi! :)
Pratik

-2

Có rất nhiều câu trả lời về chủ đề này vì vậy tôi sẽ không thêm câu trả lời.

Nhưng với một người mới bắt đầu học Observable / Angular và tự hỏi nên sử dụng cái nào so với Promise , tôi khuyên bạn nên giữ mọi thứ có thể quan sát và chuyển đổi tất cả các Promise hiện có trong dự án của bạn thành Observable.

Đơn giản là vì khung Angular và cộng đồng của nó đều sử dụng Observable. Vì vậy, sẽ rất có lợi khi bạn tích hợp các dịch vụ khung hoặc các mô-đun của bên thứ 3 và kết nối mọi thứ lại với nhau.


Mặc dù tôi đánh giá cao tất cả các downvote nhưng tôi vẫn nhấn mạnh ý kiến ​​của mình ở trên trừ khi có ai đó đưa ra một nhận xét thích hợp để liệt kê một vài tình huống có thể vẫn hữu ích trong dự án Angular của bạn để sử dụng Promise trên Observables.

Tất nhiên, không có ý kiến ​​nào đúng 100% trong mọi trường hợp nhưng ít nhất tôi nghĩ 98% thời gian cho các dự án thương mại thông thường được thực hiện trong khung Angular, Observable là cách đúng đắn.

Ngay cả khi bạn không thích nó ở điểm khởi đầu của dự án sở thích đơn giản của mình, bạn sẽ sớm nhận ra hầu hết tất cả các thành phần bạn tương tác trong Angular và hầu hết khung bên thứ 3 thân thiện của Angular đều sử dụng Observables, và sau đó bạn sẽ cuối cùng đã liên tục chuyển đổi Lời hứa của bạn thành Có thể quan sát được để liên lạc với họ.

Các thành phần này bao gồm nhưng không giới hạn ở: HttpClient, Trình tạo biểu mẫu, mô-đun / hộp thoại vật liệu góc, cửa hàng / hiệu ứng Ngrx và ngx-bootstrap.

Trên thực tế, Lời hứa duy nhất từ ​​hệ sinh thái Angular tôi đã xử lý trong 2 năm qua là APP_INITIALIZER.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.