Rumah  >  Artikel  >  hujung hadapan web  >  Menggunakan Promise untuk merangkum fungsi tak segerak dalam NodeJS_node.js

Menggunakan Promise untuk merangkum fungsi tak segerak dalam NodeJS_node.js

WBOY
WBOYasal
2016-05-16 16:13:001094semak imbas

Dalam proses menulis Node.js, operasi IO yang berterusan mungkin membawa kepada "mimpi ngeri piramid". Berbilang fungsi panggil balik menjadikan kod itu sukar untuk dikekalkan untuk merangkum fungsi tak segerak dan menggunakan API bersatu untuk menghilangkan mimpi ngeri berbilang panggilan balik.

Model IO tidak menyekat yang disediakan oleh Node.js membolehkan kami menggunakan fungsi panggil balik untuk mengendalikan operasi IO Walau bagaimanapun, apabila operasi IO berterusan diperlukan, fungsi panggil balik anda akan bersarang beberapa kali, menjadikan kod itu sangat tidak sedap dipandang. untuk mengekalkan. Dan mungkin terdapat banyak kod pendua untuk pengendalian ralat, yang dipanggil "Pyramid of Doom".

Salin kod Kod adalah seperti berikut:

langkah1(fungsi (nilai1) {
Langkah2(nilai1, fungsi(nilai2) {
         langkah3(nilai2, fungsi(nilai3) {
              langkah4(nilai3, fungsi(nilai4) {
// Lakukan sesuatu dengan nilai4
            });
        });
});
});

Ini sebenarnya masalah dengan aliran Kawalan Node.js Terdapat banyak penyelesaian untuk masalah ini, seperti menggunakan async, atau eventProxy, dsb. Walau bagaimanapun, tema artikel ini ialah menggunakan Promise dalam spesifikasi CommonJs untuk menyelesaikan masalah ini. masalah.

Apa itu Janji?

Terdapat banyak spesifikasi Promise CommonJs Kami biasanya membincangkan spesifikasi Promise/A, yang mentakrifkan kelakuan asas Promise.

Janji ialah objek yang biasanya mewakili operasi tak segerak yang mungkin diselesaikan pada masa hadapan. Operasi ini mungkin berjaya atau gagal, jadi objek Promise biasanya mempunyai tiga keadaan: Menunggu, Dipenuhi dan Ditolak. Mewakili penyiapan yang tidak lengkap, berjaya dan kegagalan operasi masing-masing. Sebaik sahaja keadaan objek Promise berubah daripada Menunggu kepada Dipenuhi atau Ditolak, keadaannya tidak boleh diubah.

Objek Promise biasanya mempunyai kaedah kemudian, yang membolehkan kita memanipulasi nilai yang dikembalikan selepas kemungkinan kejayaan pada masa hadapan atau sebab kegagalan. Kaedah kemudian kelihatan seperti ini:

janji.kemudian(padaDitepati, padaDitolak)
Jelas sekali, kaedah kemudian menerima dua parameter, yang biasanya dua fungsi Satu digunakan untuk mengendalikan keputusan selepas operasi berjaya, dan satu lagi digunakan untuk mengendalikan sebab-sebab selepas operasi gagal adalah hasil demi kejayaan dan sebab kegagalan masing-masing. Jika parameter diserahkan kepada kaedah kemudian bukan fungsi, parameter ini akan diabaikan.

Nilai pulangan kaedah kemudian adalah objek Promise Ciri ini membolehkan kita membuat panggilan berantai kemudian untuk mencapai kesan mengawal aliran. Terdapat banyak isu terperinci di sini, seperti pemindahan nilai atau pengendalian ralat. Spesifikasi Promise ditakrifkan seperti berikut:

Nilai pulangan bagi fungsi onFulfilled atau onRejected bukan objek Promise, maka nilai ini akan digunakan sebagai parameter pertama onFulfilled dalam kaedah seterusnya Jika nilai pulangan ialah objek Promise, mengapa nilai pulangan daripada kaedah itu objek Janji
Jika pengecualian dilemparkan dalam fungsi onFulfilled atau onRejected, status objek Promise yang dikembalikan oleh kaedah kemudian akan ditukar kepada Rejected Jika objek Promise memanggil kemudian, objek Ralat akan digunakan sebagai parameter pertama fungsi onRejected
Jika status Promise menjadi Ditepati dan tiada fungsi onFulfilled disediakan dalam kaedah itu, status objek Promise yang dikembalikan oleh kaedah itu menjadi Ditepati dan hasil yang berjaya adalah hasil daripada Promise sebelumnya. Begitu juga dengan Rejected.
Selain itu, onFulfilled dan onRejected dilaksanakan secara tak segerak.

Pelaksanaan standard: q

Di atas ialah spesifikasi Promise, dan apa yang kami perlukan ialah pelaksanaannya q ialah perpustakaan dengan spesifikasi pelaksanaan yang lebih baik untuk Promise/A.

Mula-mula kita perlu membuat objek Promise Spesifikasi untuk penciptaan objek Promise adalah dalam Promise/B Saya tidak akan memberikan penjelasan terperinci di sini, hanya pergi ke kod.

Salin kod Kod adalah seperti berikut:

Fungsi(bendera){
         var defer = q.defer();
             fs.readFile("a.txt", fungsi (err, data){
If(err) defer.reject(err);
                 lain tunda.selesai(data);
            });
                balik tangguh.janji;
}

Kebanyakan pelaksanaan Promise adalah serupa dalam penciptaan Promise Dengan mencipta objek defer dengan atribut promise, jika nilai berjaya diperoleh, defer.resolve(value) dipanggil Jika gagal, defer.reject(reason ) dipanggil Akhirnya, kembalikan atribut janji penangguhan. Proses ini boleh difahami sebagai memanggil defer.resolve untuk menukar status Promise kepada Ditepati, dan memanggil defer.reject untuk menukar status Promise kepada Ditolak.

Apabila berhadapan dengan satu siri kaedah tak segerak yang berterusan, bagaimana menggunakan Promise untuk menulis kod yang cantik? Sila lihat contoh di bawah.

Salin kod Kod adalah seperti berikut:

promise0.then(fungsi(hasil){
              // melakukan sesuatu
        pulangkan hasil;
}).kemudian(fungsi(hasil) {
              // melakukan sesuatu
          balas janji1;                                          }).kemudian(fungsi(hasil) {
              // melakukan sesuatu
}).tangkap(fungsi(cth) {
console.log(ex);
}).akhirnya(fungsi(){
console.log("final");
});

Dalam kod di atas, kaedah kemudian hanya menerima OnFulfilled, dan kaedah tangkapan sebenarnya kemudian (null, OnRejected Dalam kes ini, selagi satu siri kaedah tak segerak sentiasa mengembalikan nilai, kod itu akan). menjadi gaya air terjun, jika mana-mana kaedah tak segerak gagal atau pengecualian berlaku, maka menurut spesifikasi CommonJs Promise, fungsi dalam tangkapan akan dilaksanakan. q juga menyediakan kaedah akhirnya, yang mudah difahami secara literal, iaitu, tanpa mengira penyelesaian atau menolak, fungsi dalam akhirnya akan dilaksanakan.

Nampak bagus, kod lebih boleh diselenggara dan cantik, jadi bagaimana jika anda mahu concurrency?

Salin kod Kod adalah seperti berikut:
​ q.all([promise0, promise1, promise2]).spread(function(val0, val1, val2){
console.log(argumen);
                    }).kemudian(fungsi(){
console.log("selesai");
                  }).tangkap(fungsi(err){
console.log(err);
                });

Q juga menyediakan API untuk concurrency Call the all method dan lulus array Promise untuk terus menggunakan gaya rantaian. Terdapat juga perkara seperti q.nfbind yang boleh menukar API asli Node.js kepada Promise untuk menyatukan format kod, yang juga sangat bagus. Lebih banyak API tidak akan diterangkan secara terperinci di sini.

Kesimpulan

Artikel ini terutamanya memperkenalkan penggunaan Promise untuk menyelesaikan masalah aliran kawalan Node.js, tetapi Promise juga boleh digunakan pada bahagian hadapan EMCAScript6 telah menyediakan sokongan API asli. Perlu diingatkan bahawa Promise bukan satu-satunya penyelesaian async juga merupakan pilihan yang baik dan menyediakan API kawalan konkurensi yang lebih mesra Walau bagaimanapun, saya fikir Promise mempunyai lebih banyak kelebihan apabila merangkum fungsi dengan kaedah tak segerak.

Baiklah, artikel ini berakhir di sini, saya harap ia dapat membantu semua orang.

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn