Memahami janji di Node.js


147

Dari apa yang saya mengerti ada tiga cara memanggil kode asinkron:

  1. Acara, mis request.on("event", callback);
  2. Panggilan balik, mis fs.open(path, flags, mode, callback);
  3. Janji

Saya menemukan perpustakaan node-janji tapi saya tidak mengerti.

Bisakah seseorang menjelaskan tentang janji-janji itu dan mengapa saya harus menggunakannya?

Juga, mengapa itu dihapus dari Node.js?


Artikel ini menjelaskannya dengan cukup baik. Ketika datang ke implementasi yang dapat digunakan di node.js, lihat Futures
Sean Kinsey

Berikut ini adalah seri hebat yang saya gunakan untuk membuat kelas janji saya sendiri: Mari Membuat Kerangka Kerja: Janji Inilah video tentang jQuery Ditangguhkan: blog.bigbinary.com/2011/09/03/jquery-deferred.html
Tom Winter

Jawaban:


91

Janji dalam node.js berjanji untuk melakukan beberapa pekerjaan dan kemudian memiliki callback terpisah yang akan dieksekusi untuk keberhasilan dan kegagalan serta menangani batas waktu. Cara lain untuk memikirkan janji-janji di node.js adalah bahwa mereka adalah penghasil emisi yang hanya dapat memancarkan dua peristiwa: sukses dan kesalahan.

Hal paling keren tentang janji adalah Anda bisa menggabungkannya ke dalam rantai ketergantungan (lakukan Promise C hanya saat Promise A dan Promise B selesai).

Dengan menghapusnya dari inti node.js, itu menciptakan kemungkinan membangun modul dengan implementasi janji yang berbeda yang dapat duduk di atas inti. Beberapa di antaranya adalah simpul-janji dan masa depan .


10
@ Wang Tidak itu tidak.
Ivo Wetzel

98

Karena pertanyaan ini masih memiliki banyak pandangan (seperti milik saya), saya ingin menunjukkan bahwa:

  1. simpul-janji tampak agak mati bagi saya (komit terakhir sekitar 1 tahun yang lalu) dan hampir tidak berisi tes.
  2. The berjangka modul terlihat sangat membengkak dengan saya dan buruk didokumentasikan (dan saya berpikir bahwa konvensi penamaan yang hanya buruk)
  3. Cara terbaik untuk pergi tampaknya adalah kerangka q , yang aktif dan terdokumentasi dengan baik.

9
Periksa juga ini github.com/medikoo/deferred , Q adalah salah satu yang pertama dan itu pasti inspirasi bagi banyak implementasi yang muncul setelah itu, tapi sayangnya itu sangat lambat dan terlalu "teoretis" di beberapa bagian, Q tidak cocok dengan beberapa skenario dunia nyata
Mariusz Nowak

Saya akan memeriksa video ini dengan janji oleh salah satu pembuat RSVP.js youtube.com/...
runspired

23
Pembaruan 2014 - bluebird sejauh ini merupakan yang tercepat dan yang memiliki kemampuan debugging terbaik saat ini.
Benjamin Gruenbaum

19

Sebuah janji adalah "hal" yang mewakili hasil "akhirnya" dari suatu operasi. Poin yang perlu diperhatikan di sini adalah, hal itu meringkas detail ketika sesuatu terjadi dan memungkinkan Anda untuk fokus pada apa yang harus terjadi setelah sesuatu itu terjadi. Ini akan menghasilkan kode yang bersih dan dapat dipertahankan di mana alih-alih memiliki panggilan balik di dalam panggilan balik di dalam panggilan balik, kode Anda akan terlihat seperti:

 var request = new Promise(function(resolve, reject) {
   //do an ajax call here. or a database request or whatever.
   //depending on its results, either call resolve(value) or reject(error)
   //where value is the thing which the operation's successful execution returns and
   //error is the thing which the operation's failure returns.
 });

 request.then(function successHandler(result) {
   //do something with the result
 }, function failureHandler(error) {
  //handle
 });

Spesifikasi janji menyatakan bahwa janji itu

then

Metode harus mengembalikan janji baru yang dipenuhi ketika suksesHandler yang diberikan atau callback kegagalanHandler selesai. Ini berarti bahwa Anda dapat menjalin janji bersama ketika Anda memiliki serangkaian tugas asinkron yang perlu dilakukan dan diyakinkan bahwa urutan operasi dijamin sama seperti jika Anda telah menggunakan panggilan balik. Jadi alih-alih meneruskan panggilan balik di dalam panggilan balik di dalam panggilan balik, kode dengan janji dirantai tampak seperti:

var doStuff = firstAsyncFunction(url) {
                return new Promise(function(resolve, reject) {
                       $.ajax({
                        url: url,
                        success: function(data) {
                            resolve(data);
                        },
                        error: function(err) {
                             reject(err); 
                        } 
                  });
               };
doStuff
  .then(secondAsyncFunction) //returns a promise
  .then(thirdAsyncFunction); //returns a promise

Untuk mengetahui lebih banyak tentang janji-janji dan mengapa janji itu sangat keren, periksa blog Domenic: http://domenic.me/2012/10/14/youre-missing-the-point-of-promises/


12

Tutorial baru ini tentang Janji dari penulis PouchDB mungkin adalah yang terbaik yang pernah saya lihat di mana saja. Ini dengan bijak mencakup kesalahan rookie klasik yang menunjukkan pola penggunaan yang benar dan bahkan beberapa pola-anti yang masih umum digunakan - bahkan dalam tutorial lainnya !!

Nikmati!

PS Saya tidak menjawab beberapa bagian lain dari pertanyaan ini karena sudah dibahas dengan baik oleh orang lain.


Satu-satunya permintaan maaf saya untuk ini adalah memaksa Anda untuk membaca humor di akhir kesalahan tingkat lanjut # 4.
Tony O'Hagan

Bahkan, kode dalam tutorial yang mereka klaim sebagai antipemut membutuhkan sarang untuk loop dan kondisinya, dan tidak dapat dengan mudah diratakan seperti yang mereka sarankan.
Bergi

Kesalahan tingkat lanjut # 4 juga dapat diselesaikan dengan menggunakan sejumlah besar pendekatan yang berbeda, lihat Bagaimana cara mengakses hasil janji sebelumnya dalam rantai .then ()? ( pola penutupan yang mereka sarankan tampaknya tidak terlalu populer).
Bergi

Saya pikir jawaban hanya tautan ini sebaiknya menjadi komentar. Harap cantumkan setidaknya poin utama dari artikel itu dalam jawaban Anda di sini.
Bergi

7

Mike Taulty memiliki serangkaian video , masing-masing berdurasi kurang dari sepuluh menit, menggambarkan cara kerja perpustakaan WinJS Promise.

Video-video ini cukup informatif, dan Mike berhasil menunjukkan kekuatan API Janji dengan beberapa contoh kode yang dipilih dengan baik.

var twitterUrl = "http://search.twitter.com/search.json?q=windows";
var promise = WinJS.xhr({ url: twitterUrl });

 promise = promise.then(
     function (xhr) {
     },
     function (xhr) {
         // handle error
     });

Perlakuan tentang bagaimana pengecualian ditangani sangat baik.

Terlepas dari referensi WinJs, ini adalah seri video minat umum, karena API Janji secara luas serupa di banyak implementasinya.

RSVP adalah implementasi Promise yang ringan yang lolos dari test suite Promise / A +. Saya sangat suka API, karena mirip dengan antarmuka WinJS.

Perbarui Apr-2014

Kebetulan, perpustakaan WinJS sekarang open source .


1
+1. Ini adalah contoh pertama yang saya lihat yang masuk akal bagi saya dan intuitif untuk digunakan. Entah bagaimana otak saya tidak dapat menguraikan semua deferredsdan resolvedan deferred.promise.thendan menentukan dari promiseActionsdalam dokumentasi perpustakaan Q populer. Apakah Anda tahu sesuatu yang sederhana ini untuk Node.js ?
Redsandro

1
@noel terima kasih telah berbagi tautan di atas, ini adalah seri pengantar yang sangat baik untuk janji, dan saya setuju bahwa spesifikasi WinJS tidak relevan karena pendekatan / topik keseluruhan bersifat universal.
arcseldon

Contoh yang bagus. Juga saya memperbaiki tautan pertama Anda yang sudah mati
stonedauwg

5

Keuntungan lain dari janji adalah bahwa penanganan kesalahan dan pengecualian melempar dan menangkap jauh lebih baik daripada mencoba menanganinya dengan panggilan balik.

The bluebird perpustakaan menerapkan janji-janji dan memberikan jejak stack panjang besar, sangat cepat, dan memperingatkan tentang kesalahan yang tidak tertangkap. Ini juga lebih cepat dan menggunakan lebih sedikit memori daripada perpustakaan janji lainnya, menurut http://bluebirdjs.com/docs/benchmarks.html


4

Apa sebenarnya janji itu?

Sebuah janji hanyalah sebuah objek yang merepresentasikan hasil dari operasi async. Janji dapat berupa salah satu dari 3 negara berikut:

pending :: Ini adalah kondisi awal, artinya janji tidak terpenuhi atau ditolak.

terpenuhi :: Ini berarti janji telah terpenuhi, berarti nilai yang diwakili oleh janji siap digunakan.

ditolak :: Ini berarti operasi gagal dan karenanya tidak dapat memenuhi janji. Terlepas dari negara, ada tiga entitas penting yang terkait dengan janji yang benar-benar perlu kita pahami

  1. fungsi pelaksana :: fungsi pelaksana mendefinisikan operasi async yang perlu dilakukan dan yang hasilnya diwakili oleh janji. Ini memulai eksekusi segera setelah objek janji diinisialisasi.

  2. resolving :: resolve adalah parameter yang diteruskan ke fungsi eksekutor, dan seandainya eksekutor berjalan dengan sukses maka resolusinya disebut dengan meneruskan hasil.

  3. reject :: reject adalah parameter lain yang diteruskan ke fungsi pelaksana, dan digunakan ketika fungsi pelaksana gagal. Alasan kegagalan bisa diteruskan ke tolak.

Jadi, setiap kali kita membuat objek janji, kita harus menyediakan Pelaksana, Putuskan dan Tolak.

Referensi :: Janji


0

Saya juga telah melihat janji-janji di node.js baru-baru ini. Sampai saat ini, when.js tampaknya menjadi jalan yang harus ditempuh karena kecepatan dan penggunaan sumber dayanya, tetapi dokumentasi tentang q.js memberi saya pemahaman yang jauh lebih baik. Jadi gunakan when.js tetapi q.js docs untuk memahami subjek.

Dari q.js readme on github:

Jika suatu fungsi tidak bisa mengembalikan nilai atau melempar pengecualian tanpa memblokir, itu bisa mengembalikan janji. Sebuah janji adalah objek yang mewakili nilai balik atau pengecualian yang dibuang oleh fungsi yang akhirnya bisa diberikan. Janji juga dapat digunakan sebagai proksi untuk objek jarak jauh untuk mengatasi latensi.


0

Obyek janji merupakan penyelesaian atau kegagalan operasi asinkron.

Jadi untuk menerapkan janji, Anda perlu dua bagian: -

1. Menciptakan Janji:

Konstruktor janji menerima fungsi yang disebut pelaksana yang memiliki 2 parameter menyelesaikan dan menolak.

function example(){
   return new Promise (function(resolve , reject){   //return promise object
      if(success){
         resolve('success');  //onFullfiled
      }else{
         reject('error');     //onRejected
      }
   })
}

2. Menangani Janji:

Objek janji memiliki 3 metode untuk menangani objek janji: -

1. Promise.prototipe.catch (onRejected)

2. Promise.prototype.then (onFullfiled)

3. Promise.prototipe.akhirnya (onFullfiled, onRejected)

example.then((data) =>{
  //handles resolved data
  console.log(data); //prints success     
}).catch((err) => {
  //handles rejected error 
  console.log(err);  //prints error
})
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.