Pertanyaan Janji vs Dapat Diobservasi


Bisakah seseorang menjelaskan perbedaannya Promise dan Observable di Angular?

Contoh pada masing-masing akan sangat membantu dalam memahami kedua kasus. Dalam skenario apa kita bisa menggunakan setiap kasus?


761
2018-05-21 15:43


asal


Jawaban:


Janji

SEBUAH Promise menangani a acara tunggal ketika operasi async selesai atau gagal.

Catatan: Ada Promise perpustakaan di luar sana yang mendukung pembatalan, tetapi ES6 Promise tidak sejauh ini.

Tampak

Sebuah Observable seperti sebuah Stream (dalam banyak bahasa) dan memungkinkan untuk melewati nol atau lebih banyak peristiwa di mana callback dipanggil untuk setiap peristiwa.

Sering Observable lebih disukai daripada Promise karena menyediakan fitur Promise dan banyak lagi. Dengan Observable tidak masalah jika Anda ingin menangani 0, 1, atau beberapa acara. Anda dapat menggunakan API yang sama dalam setiap kasus.

Observable juga memiliki kelebihan Promise menjadi dapat dibatalkan. Jika hasil permintaan HTTP ke server atau beberapa operasi async mahal lainnya tidak diperlukan lagi, Subscription dari sebuah Observable memungkinkan untuk membatalkan langganan, sementara a Promise pada akhirnya akan memanggil keberhasilan atau panggilan balik yang gagal bahkan ketika Anda tidak memerlukan pemberitahuan atau hasil yang diberikan lagi.

Dapat diamati menyediakan operator seperti map, forEach, reduce, ... mirip dengan array

Ada juga operator yang kuat seperti retry(), atau replay(), ... yang sering sangat berguna.


907
2018-05-21 17:19



Janji:

  • mengembalikan satu nilai
  • tidak dapat dibatalkan
  • kode yang lebih mudah dibaca dengan mencoba / menangkap dan async / menunggu

Dapat diamati:

  • bekerja dengan banyak nilai dari waktu ke waktu
  • dapat dibatalkan
  • dukung peta, filter, kurangi dan operator serupa
  • gunakan Ekstensi Reaktif (RxJS)
  • sebuah array yang itemnya tiba secara asynchronous dari waktu ke waktu

239
2018-06-07 12:39



Kedua Promises dan Observables berikan kami abstraksi yang membantu kami menangani asynchronous sifat aplikasi kami. Perbedaan antara mereka ditunjukkan dengan jelas oleh @ Günter dan @Relu.

Karena cuplikan kode bernilai seribu kata, lepaskan contoh di bawah untuk memahaminya lebih mudah.

Terima kasih @Christoph Burgdorf untuk yang luar biasa artikel


Angular menggunakan Rx.js Observables bukan janji untuk berurusan dengan HTTP.

Misalkan Anda sedang membangun sebuah fungsi pencarian yang akan langsung menunjukkan hasil saat Anda mengetik. Terdengar akrab tetapi ada banyak tantangan yang datang dengan tugas itu.

  • Kami tidak ingin menekan endpoint server setiap kali pengguna menekan tombol, itu harus membanjiri mereka dengan badai HTTP permintaan. Pada dasarnya, kami hanya ingin menekannya setelah pengguna berhenti mengetik bukan dengan setiap keystroke.
  • Jangan menekan titik akhir pencarian dengan params kueri yang sama untuk permintaan selanjutnya.
  • Berurusan dengan respons out-of-order. Ketika kami memiliki beberapa permintaan dalam penerbangan pada saat yang sama, kami harus memperhitungkan kasus-kasus di mana mereka kembali dalam urutan yang tidak diharapkan. Bayangkan kita pertama mengetik komputer, berhenti, permintaan keluar, kami mengetik mobil, berhenti, permintaan keluar. Sekarang kami memiliki dua permintaan dalam penerbangan. Sayangnya, permintaan yang membawa hasil untuk komputer kembali setelah permintaan yang membawa hasil mobil.

Demo hanya akan terdiri dari dua file: app.ts dan wikipedia-service.ts. Dalam skenario dunia nyata, kita kemungkinan besar akan memisahkan lebih jauh.


Dibawah ini Berdasarkan janji penerapan yang tidak menangani salah satu kasus tepi yang dideskripsikan.

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]);
  }
}

Kami sedang menyuntikkan Jsonp layanan untuk membuat GET permintaan terhadap API Wikipedia dengan istilah pencarian yang diberikan. Perhatikan bahwa kita memanggil toPromise untuk mendapatkan dari Observable<Response> ke a Promise<Response>. Akhirnya berakhir dengan Promise<Array<string>> sebagai jenis kembalinya metode pencarian kami.

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

Tidak terlalu mengejutkan juga di sini. Kami menyuntikkan kami WikipediaService dan memaparkan fungsionalitasnya melalui metode pencarian ke template. Template hanya mengikat keyup dan panggilan search(term.value).

Kami membukanya dari hasil Janji bahwa metode pencarian WikipediaService mengembalikan dan memaparkannya sebagai Array string sederhana ke template sehingga kita dapat memiliki *ngFor melaluinya dan membuat daftar untuk kami.

Lihat contohnya Berdasarkan janji implementasi pada Plunker


Dimana Dapat diamati sangat bersinar

Mari ubah kode agar tidak memalu titik akhir dengan setiap ketukan tetapi sebaliknya hanya mengirim permintaan saat pengguna berhenti mengetik 400 ms

Untuk mengungkap kekuatan super seperti itu pertama-tama kita perlu mendapatkan Observable<string> yang membawa istilah pencarian yang digunakan pengguna. Alih-alih mengikat secara manual ke acara kunci, kita dapat memanfaatkan Angular's formControl direktif. Untuk menggunakan petunjuk ini, pertama kita perlu mengimpor ReactiveFormsModule ke dalam modul aplikasi kami.

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 {}

Setelah diimpor, kita dapat menggunakan formControl dari dalam template kami dan mengaturnya ke nama "istilah".

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

Dalam komponen kami, kami membuat turunan dari FormControl dari @angular/form dan memaparkannya sebagai bidang di bawah istilah nama pada komponen kami.

Dibalik layar, istilah secara otomatis mengekspos Observable<string> sebagai properti valueChanges yang dapat kami berlangganan. Sekarang kita punya Observable<string>, mengatasi input pengguna semudah menelepon debounceTime(400) pada kita Observable. Ini akan mengembalikan yang baru Observable<string> yang hanya akan memancarkan nilai baru ketika belum ada nilai baru untuk 400 md.

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

Ini akan membuang-buang sumber daya untuk mengirim permintaan lain untuk istilah pencarian yang sudah diperlihatkan oleh aplikasi kami. Yang harus kita lakukan untuk mencapai perilaku yang diinginkan adalah memanggil distinctUntilChanged operator tepat setelah kami menelepon debounceTime(400)

Lihat contohnya Tampak implementasi pada Plunker

Untuk menangani tanggapan yang tidak sesuai pesanan, silakan periksa artikel lengkapnya    http://blog.thoughtram.io/angular/2016/01/06/taking-advantage-of-observables-in-angular2.html

Sejauh saya menggunakan Http di Angular, saya setuju bahwa dalam kasus penggunaan normal tidak ada banyak perbedaan ketika menggunakan Observable over Promise. Tidak ada kelebihan yang benar-benar relevan di sini dalam praktiknya. Semoga saya bisa melihat beberapa kasus penggunaan lanjutan di masa depan :)


Belajarlah lagi


199
2017-10-19 15:17



Kedua Janji dan Dapat diamati akan membantu kami bekerja dengan fungsi asynchronous di JavaScript. Mereka sangat mirip dalam banyak kasus, namun, masih ada beberapa perbedaan antara keduanya juga, janji-janji adalah nilai-nilai yang akan menyelesaikannya asynchronous cara seperti http panggilan. Di sisi lain, observable berurusan dengan urutan peristiwa asynchronous. Perbedaan utama tercantum sebagai berikut:

janji:

  • memiliki satu jalur pipa
  • biasanya hanya digunakan dengan pengembalian data async
  • tidak mudah dibatalkan

tampak:

  • dapat dibatalkan
  • dapat dipulihkan oleh alam seperti coba lagi dan coba lagi Saat
  • streaming data dalam beberapa jalur pipa
  • memiliki operasi seperti array seperti peta, filter dll
  • dapat dibuat dari sumber lain seperti acara
  • mereka berfungsi, yang nantinya bisa berlangganan

Juga, saya telah membuat gambar grafis untuk Anda di bawah ini untuk menunjukkan perbedaannya secara visual:

Promises and Observables image


118
2018-05-07 06:56



Janji

  1. Definisi: Membantu Anda menjalankan fungsi secara asinkron, dan menggunakan nilai pengembaliannya (atau pengecualian), tetapi hanya sekali ketika dieksekusi.
  2. Tidak malas
  3. Tidak dapat dibatalkan. Dua kemungkinan keputusan itu
    • Menolak
    • Menyelesaikan
  4. Tidak bisa retried(Janji harus memiliki akses ke fungsi asli yang mengembalikan janji untuk memiliki kemampuan mencoba lagi, yang merupakan praktik buruk)

Dapat diamati

  1. Definisi: Membantu Anda menjalankan fungsi secara asinkron, dan menggunakan nilai kembaliannya dalam urutan berkelanjutan (beberapa kali) saat dieksekusi.
  2. Secara default, itu Malas karena memancarkan nilai ketika waktu berjalan.
  3. Memiliki banyak operator yang menyederhanakan upaya pengkodean.
  4. Satu operator mencoba kembali dapat digunakan untuk mencoba kembali jika diperlukan, juga jika kita perlu mencoba kembali pengamatan berdasarkan beberapa kondisi coba lagi dapat digunakan.

    Catatan: Daftar operator beserta diagram interaktifnya tersedia di sini di RxMarbles.com


41
2018-01-09 18:29



Ada satu sisi buruk dari Observables yang hilang dalam jawaban. Janji memungkinkan untuk menggunakan fungsi async / menunggu ES7. Dengan mereka, Anda dapat menulis kode asinkron seperti itu akan menjadi panggilan fungsi sinkron, sehingga Anda tidak perlu callback lagi. Satu-satunya kemungkinan bagi Orang-Orang Terlihat untuk melakukan ini, adalah mengonversinya menjadi Janji. Tetapi ketika Anda mengonversinya menjadi Janji, Anda hanya dapat memiliki satu nilai pengembalian lagi:

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

Bacaan lebih lanjut: Bagaimana saya bisa `menunggu` di Rx Observable? 


26
2018-06-28 20:45



Saya seorang pria gambar, ini hilang dalam jawaban lain:

enter image description here


15
2017-12-06 19:17



 Promises vs Observables

janji-janji dan dapat diamati keduanya menangani panggilan asynchronous saja. temukan di atas   gambar untuk perbedaan utama.


13
2018-01-17 16:50