Saya ingin bekerja dengan janji-janji tetapi saya memiliki API panggilan balik dalam format seperti:
1. Beban DOM atau acara satu kali lainnya:
window.onload; // set to callback
...
window.onload = function() {
};
2. Panggilan balik polos:
function request(onChangeHandler) {
...
}
request(function() {
// change happened
...
});
3. Callback gaya simpul ("nodeback"):
function getStuff(dat, callback) {
...
}
getStuff("dataParam", function(err, data) {
...
})
4. Seluruh perpustakaan dengan panggilan balik gaya simpul:
API;
API.one(function(err, data) {
API.two(function(err, data2) {
API.three(function(err, data3) {
...
});
});
});
new Promise
penambahan overhead signifikan? Saya ingin membungkus semua fungsi Noje.js sinkron saya dalam Janji sehingga dapat menghapus semua kode sinkron dari aplikasi Node saya, tetapi apakah ini praktik terbaik? Dengan kata lain, fungsi yang menerima argumen statis (misalnya string) dan mengembalikan hasil yang dihitung, haruskah saya membungkusnya dengan janji? ... Saya membaca di suatu tempat bahwa Anda seharusnya tidak memiliki kode sinkron di Nodejs.Jawaban:
Janji memiliki status, mereka mulai tertunda dan dapat puas dengan:
Fungsi janji pengembalian tidak boleh dibuang , mereka harus mengembalikan penolakan sebagai gantinya. Melempar dari fungsi pengembalian janji akan memaksa Anda untuk menggunakan a
} catch {
dan a.catch
. Orang-orang yang menggunakan API yang dijanjikan tidak berharap untuk membuang janji. Jika Anda tidak yakin bagaimana API async bekerja di JS - silakan lihat jawaban ini terlebih dahulu.1. Beban DOM atau acara satu kali lainnya:
Jadi, membuat janji umumnya berarti menentukan kapan mereka puas - itu berarti ketika mereka pindah ke fase yang dipenuhi atau ditolak untuk menunjukkan data tersedia (dan dapat diakses dengan
.then
).Dengan implementasi janji modern yang mendukung
Promise
konstruktor seperti ES6 asli menjanjikan:Anda kemudian akan menggunakan janji yang dihasilkan seperti:
Dengan pustaka yang mendukung ditangguhkan (Mari gunakan $ q untuk contoh ini di sini, tetapi kami juga akan menggunakan jQuery nanti):
Atau dengan jQuery seperti API, mengaitkan peristiwa yang terjadi sekali:
2. Panggilan balik polos:
API ini agak umum karena ... panggilan balik umum di JS. Mari kita lihat kasus umum memiliki
onSuccess
danonFail
:Dengan implementasi janji modern yang mendukung
Promise
konstruktor seperti ES6 asli menjanjikan:Dengan pustaka yang mendukung ditangguhkan (Mari gunakan jQuery untuk contoh ini di sini, tetapi kami juga menggunakan $ q di atas):
jQuery juga menawarkan
$.Deferred(fn)
formulir, yang memiliki keuntungan memungkinkan kita untuk menulis ekspresi yang sangat mirip dengannew Promise(fn)
formulir, sebagai berikut:Catatan: Di sini kita mengeksploitasi fakta bahwa jQuery yang ditangguhkan
resolve
danreject
metode "dapat dilepas"; yaitu. mereka terikat pada instance dari jQuery.Deferred (). Tidak semua lib menawarkan fitur ini.3. Callback gaya simpul ("nodeback"):
Callback gaya simpul (nodebacks) memiliki format tertentu di mana callback selalu menjadi argumen terakhir dan parameter pertamanya adalah kesalahan. Pertama mari kita promisikan secara manual:
Untuk:
Dengan ditangguhkan Anda dapat melakukan hal berikut (mari kita gunakan Q untuk contoh ini, meskipun Q sekarang mendukung sintaks baru yang harus Anda sukai ):
Secara umum, Anda tidak boleh terlalu banyak menjanjikan hal-hal secara manual, sebagian besar perpustakaan janji yang dirancang dengan mempertimbangkan Node serta janji bawaan di Node 8+ memiliki metode bawaan untuk menjanjikan serangan balik. Sebagai contoh
4. Seluruh perpustakaan dengan panggilan balik gaya simpul:
Tidak ada aturan emas di sini, Anda menjanjikannya satu per satu. Namun, beberapa implementasi janji memungkinkan Anda melakukan ini secara massal, misalnya di Bluebird, mengonversi API nodeback ke API janji sesederhana:
Atau dengan janji asli di Node :
Catatan:
.then
pawang Anda tidak perlu menjanjikan sesuatu. Mengembalikan janji dari.then
pawang akan menyelesaikan atau menolak dengan nilai janji itu. Melempar dari.then
pawang juga merupakan praktik yang baik dan akan menolak janji - ini adalah janji keselamatan lemparan yang terkenal.onload
kasus aktual , Anda harus menggunakanaddEventListener
daripadaonX
.sumber
resolve()
danreject()
ditulis untuk dapat digunakan kembali, saya berani mengedit yang saya sarankan relevan karena menawarkan contoh jQuery dari formulir$.Deferred(fn)
, yang sebaliknya kurang. Jika hanya satu contoh jQuery yang disertakan, maka saya menyarankan bahwa itu harus dari formulir ini daripadavar d = $.Deferred();
dll karena orang harus didorong untuk menggunakan$.Deferred(fn)
formulir yang sering diabaikan , ditambah, dalam jawaban seperti ini, itu menempatkan jQuery lebih setara dengan Lib yang menggunakan Pola Konstruktor Pengungkap .$.Deferred(fn)
, jika Anda mengeditnya sebagai ganti contoh yang ada dalam 15 menit berikutnya saya yakin saya dapat mencoba menyetujuinya tepat waktu :)util.promisify
, bahwa Node.js akan ditambahkan ke intinya mulai dari RC 8.0.0. Ini berfungsi tidak jauh berbeda dari BluebirdPromise.promisify
, tetapi memiliki keuntungan karena tidak memerlukan dependensi tambahan, jika Anda hanya menginginkan Promise asli. Saya telah menulis posting blog tentang util.promisify untuk siapa saja yang ingin membaca lebih lanjut tentang topik ini.Hari ini, saya dapat menggunakan
Promise
diNode.js
sebagai metode Javascript polos.Contoh sederhana dan mendasar untuk
Promise
(dengan cara KISS ):Kode API Async Javascript Biasa :
Promise
Kode API Javascript Async:(Saya sarankan mengunjungi sumber yang indah ini )
Juga
Promise
dapat digunakan dengan bersama-samaasync\await
dalamES7
membuat menunggu aliran program untukfullfiled
hasil seperti berikut:Penggunaan lain dengan kode yang sama dengan menggunakan
.then()
metodePromise
juga dapat digunakan pada platform apa pun yang didasarkan pada Node.js sepertireact-native
.Bonus : Metode hybrid
( Metode panggilan balik diasumsikan memiliki dua parameter sebagai kesalahan dan hasil)
Metode di atas dapat merespons hasil untuk panggilan balik mode lama dan penggunaan Janji.
Semoga ini membantu.
sumber
Sebelum mengonversi fungsi sebagai janji Di Node.JS
Setelah Konversi
Jika Anda perlu menangani beberapa permintaan
sumber
Saya tidak berpikir
window.onload
saran dari @Benjamin akan bekerja sepanjang waktu, karena tidak mendeteksi apakah ia dipanggil setelah memuat. Saya telah digigit oleh banyak kali. Ini adalah versi yang harus selalu berfungsi:sumber
setTimeout(resolve, 0)
(atausetImmediate
, jika tersedia) untuk memastikan bahwa ia dipanggil secara tidak sinkron?resolve
sinkron baik-baik saja.then
Penangan Promise dijamin oleh kerangka kerja yang disebut asinkron , terlepas dari apakahresolve
disebut sinkron.Node.js 8.0.0 mencakup
util.promisify()
API baru yang memungkinkan API gaya panggilan balik Node.js dibungkus dalam fungsi yang mengembalikan Janji. Contoh penggunaanutil.promisify()
ditunjukkan di bawah ini.Lihat Dukungan yang ditingkatkan untuk Janji
sumber
Dalam kandidat rilis untuk Node.js 8.0.0, ada utilitas baru,
util.promisify
(Saya telah menulis tentang util.promisify ), yang merangkum kapasitas menjanjikan fungsi apa pun.Ini tidak jauh berbeda dari pendekatan yang disarankan dalam jawaban lain, tetapi memiliki keuntungan menjadi metode inti, dan tidak memerlukan dependensi tambahan.
Kemudian Anda memiliki
readFile
metode yang mengembalikan asliPromise
.sumber
util.promisify
dua kali (kembali pada tahun 2014 ketika pertanyaan ini ditulis, dan beberapa bulan yang lalu - yang saya dorong sebagai anggota inti Node dan merupakan versi saat ini yang kami miliki di Node). Karena belum tersedia untuk umum - saya belum menambahkannya ke jawaban ini. Kami akan sangat menghargai umpan balik penggunaan dan mengetahui beberapa kesulitan untuk memiliki dokumen yang lebih baik untuk rilis :)util.promisify
di posting blog Anda :)util.promisify.custom
simbol itu mungkin untuk menimpa hasil util.promisify? Sejujurnya ini adalah rindu yang disengaja, karena saya belum dapat menemukan kasus penggunaan yang berguna. Mungkin Anda bisa memberi saya beberapa input?fs.exists
atau API yang tidak mengikuti konvensi Node - burung bluebirdPromise.promisify
akan salah, tetapiutil.promisify
membuatnya benar.Anda dapat menggunakan janji-janji asli JavaScript dengan Node JS.
Tautan kode Cloud 9 saya: https://ide.c9.io/adx2803/native-promises-in-node
sumber
Dengan javaScript vanilla biasa, inilah solusi untuk menjanjikan panggilan balik api.
sumber
Perpustakaan Q oleh kriskowal termasuk fungsi panggilan balik ke janji. Metode seperti ini:
dapat dikonversi dengan Q.ninvoke
sumber
Q.denodeify
. Apakah kita perlu menekankan pembantu perpustakaan?Ketika Anda memiliki beberapa fungsi yang menerima panggilan balik dan Anda ingin mereka mengembalikan janji, Anda dapat menggunakan fungsi ini untuk melakukan konversi.
sumber
Di bawah simpul v7.6 + yang telah dibangun dalam janji dan async:
Cara Penggunaan:
sumber
Dalam Node.js 8 Anda dapat menjanjikan metode objek dengan cepat menggunakan modul npm ini:
https://www.npmjs.com/package/doasync
Ini menggunakan util.promisify dan Proxy sehingga objek Anda tetap tidak berubah. Memoisasi juga dilakukan dengan menggunakan WeakMaps). Berikut ini beberapa contohnya:
Dengan benda:
Dengan fungsi:
Anda bahkan dapat menggunakan asli
call
danapply
untuk mengikat beberapa konteks:sumber
Anda dapat menggunakan Promise asli di ES6, untuk contoh berurusan dengan setTimeout:
Dalam contoh ini, Janji tidak memiliki alasan untuk gagal, jadi
reject()
tidak pernah disebut.sumber
The gaya callback fungsi selalu seperti ini (hampir semua fungsi dalam node.js gaya ini):
Gaya ini memiliki fitur yang sama:
fungsi callback dilewatkan oleh argumen terakhir.
fungsi callback selalu menerima objek kesalahan sebagai argumen pertama.
Jadi, Anda bisa menulis fungsi untuk mengonversi fungsi dengan gaya ini seperti ini:
Untuk lebih ringkas, contoh di atas digunakan ramda.js. Ramda.js adalah perpustakaan yang sangat baik untuk pemrograman fungsional. Dalam kode di atas, kami menggunakan itu berlaku (seperti javascript
function.prototype.apply
) dan menambahkan (seperti javascriptfunction.prototype.push
). Jadi, kita bisa mengonversi fungsi gaya panggilan balik ke fungsi gaya janji sekarang:toPromise dan checkErr fungsi sendiri oleh mengamuk perpustakaan, itu adalah fungsional pemrograman perpustakaan fork oleh ramda.js (buat oleh saya).
Semoga jawaban ini bermanfaat bagi Anda.
sumber
Anda dapat melakukan sesuatu seperti ini
Lalu gunakan itu
sumber
es6-promisify
mengonversi fungsi berbasis panggilan balik ke fungsi berbasis Janji.Ref: https://www.npmjs.com/package/es6-promisify
sumber
Versi
callback
fungsi saya yang dijanjikan adalahP
fungsi:The
P
Fungsi mensyaratkan bahwa tanda tangan callback haruscallback(error,result)
.sumber
util.promisify(fn)
(err, value) => ...
atau Anda harus mendefinisikan yang kustom (lihat fungsi Custom promisified). Terima kasih catcha baik.var P = function (fn, ...args) { return new Promise((resolve, reject) => fn.call(this, ...args, (error, result) => error ? reject(error) : resolve(result))); };
akan melakukan hal yang sama seperti milik Anda dan itu jauh lebih sederhana.Di bawah ini adalah implementasi bagaimana suatu fungsi (API panggilan balik) dapat dikonversi menjadi janji.
sumber
Ini seperti 5 tahun terlambat, tapi saya ingin memposting di sini versi promesify saya yang mengambil fungsi dari callback API dan mengubahnya menjadi janji-janji
Lihatlah versi yang sangat sederhana ini di sini: https://gist.github.com/jdtorregrosas/aeee96dd07558a5d18db1ff02f31e21a
sumber