Saya telah menggunakan ES6 Promise.
Biasanya, Janji dibuat dan digunakan seperti ini
new Promise(function(resolve, reject){
if (someCondition){
resolve();
} else {
reject();
}
});
Tetapi saya telah melakukan sesuatu seperti di bawah ini untuk mengambil tekad di luar demi fleksibilitas.
var outsideResolve;
var outsideReject;
new Promise(function(resolve, reject) {
outsideResolve = resolve;
outsideReject = reject;
});
Dan kemudian
onClick = function(){
outsideResolve();
}
Ini berfungsi dengan baik, tetapi apakah ada cara yang lebih mudah untuk melakukan ini? Jika tidak, apakah ini praktik yang baik?
javascript
promise
es6-promise
Morio
sumber
sumber
Promise
harus dijalankan secara serempak untuk memungkinkan "mengekspor" dua fungsi.Jawaban:
Tidak, tidak ada cara lain untuk melakukan ini - satu-satunya hal yang dapat saya katakan adalah bahwa use case ini tidak terlalu umum. Seperti yang dikatakan Felix dalam komentar - apa yang Anda lakukan akan konsisten bekerja.
Perlu disebutkan bahwa alasan konstruktor janji berperilaku seperti ini adalah keselamatan lemparan - jika pengecualian yang tidak Anda antisipasi terjadi saat kode Anda berjalan di dalam konstruktor janji, maka akan berubah menjadi penolakan, bentuk keselamatan lemparan ini - mengubah kesalahan yang dilemparkan ke penolakan adalah penting dan membantu mempertahankan kode yang dapat diprediksi.
Untuk alasan keamanan lemparan ini, konstruktor janji dipilih lebih dari yang ditangguhkan (yang merupakan cara konstruksi janji alternatif yang memungkinkan apa yang Anda lakukan) - seperti untuk praktik terbaik - saya akan meneruskan elemen dan menggunakan konstruktor janji sebagai gantinya:
Untuk alasan ini - kapan pun Anda dapat menggunakan konstruktor janji daripada mengekspor fungsi - Saya sarankan Anda menggunakannya Setiap kali Anda dapat menghindari keduanya - hindari keduanya dan rantai.
Perhatikan, bahwa Anda tidak boleh menggunakan konstruktor janji untuk hal-hal seperti
if(condition)
, contoh pertama dapat ditulis sebagai:sumber
Promise
rantai? Misalnya dalam kasus khusus saya, saya berada di server, menunggu balasan klien tertentu (goyangan tangan SYN-ACK-agak untuk memastikan klien berhasil memperbarui keadaan).sederhana:
sumber
promiseResolve()
. Semantik dari sebuah janji adalah bahwa ia selalu mengembalikan nilai. Juga ini secara fungsional sama dengan posting OP, saya tidak mendapatkan masalah apa yang diselesaikan dengan cara yang dapat digunakan kembali.promiseResolve()
tidak akan memunculkan eksepsi. Anda dapat mendefinisikan.catch
pada konstruktor dan tidak peduli apa kode menyebutnya, konstruktor.catch
akan dipanggil. Inilah jsbin yang menunjukkan cara kerjanya: jsbin.com/yicerewivo/edit?js,consoleAgak terlambat ke pesta di sini, tetapi cara lain untuk melakukannya adalah dengan menggunakan objek Ditangguhkan . Pada dasarnya Anda memiliki jumlah pelat yang sama, tetapi sangat berguna jika Anda ingin membagikannya dan mungkin menyelesaikannya di luar definisi mereka.
Implementasi Naif:
Versi ES5:
sumber
resolve|reject
ditugaskan secara leksikal atau melaluibind
. Ini hanyalah implementasi sederhana dari objek jQuery Deferred yang telah ada sejak 1.0 (ish). Ia bekerja persis seperti janji, kecuali tidak ada keamanan lemparan. Inti dari pertanyaan ini adalah bagaimana cara menyimpan beberapa baris kode saat membuat janji.Deferred
sudah usang?Solusi yang saya buat pada 2015 untuk kerangka kerja saya. Saya menyebut jenis janji ini Task
sumber
Saya suka jawaban @JonJaques tapi saya ingin melangkah lebih jauh.
Jika Anda mengikat
then
dancatch
kemudianDeferred
objek, maka sepenuhnya mengimplementasikanPromise
API dan Anda dapat memperlakukannya sebagai janji danawait
itu dan semacamnya.sumber
Metode pembantu akan meringankan overhead tambahan ini, dan memberi Anda perasaan jQuery yang sama.
Penggunaan akan
Yang mirip dengan jQuery
Meskipun, dalam kasus penggunaan ini sederhana, sintaksis asli baik-baik saja
sumber
Saya menggunakan fungsi pembantu untuk membuat apa yang saya sebut "janji datar" -
Dan saya menggunakannya seperti itu -
Lihat contoh kerja lengkap -
Tampilkan cuplikan kode
Sunting: Saya telah membuat paket NPM yang disebut janji-datar dan kodenya juga tersedia di GitHub .
sumber
Anda bisa membungkus Janji dalam sebuah kelas.
sumber
Banyak jawaban di sini mirip dengan contoh terakhir dalam artikel ini . Saya menyimpan banyak Janji,
resolve()
danreject()
fungsi dan dapat ditugaskan ke variabel atau properti apa pun. Hasilnya, saya dapat membuat kode ini sedikit lebih ringkas:Berikut adalah contoh sederhana dari penggunaan versi ini
defer()
untuk menggabungkanFontFace
Janji beban dengan proses async lain:Pembaruan: 2 alternatif jika Anda ingin merangkum objek:
dan
sumber
const result = await deferred.promise;
Jawaban yang diterima salah. Ini cukup mudah menggunakan ruang lingkup dan referensi, meskipun mungkin membuat Janji puritan marah:
Kami pada dasarnya mengambil referensi ke fungsi ketetapan saat janji dibuat, dan kami mengembalikannya sehingga dapat diatur secara eksternal.
Dalam satu detik konsol akan menampilkan:
sumber
Ya kamu bisa. Dengan menggunakan
CustomEvent
API untuk lingkungan browser. Dan menggunakan proyek acara emitor di lingkungan node.js. Karena cuplikan dalam pertanyaan adalah untuk lingkungan peramban, berikut adalah contoh yang berfungsi untuk hal yang sama.Semoga jawaban ini bermanfaat!
sumber
Solusi kami adalah menggunakan penutupan untuk menyimpan fungsi tekad / tolak dan juga lampirkan fungsi untuk memperpanjang janji itu sendiri.
Berikut polanya:
Dan menggunakannya:
sumber
promise.resolve_ex = _resolve; promise.reject_ex = _reject;
... masih berfungsi dengan baik.Saya menemukan diri saya kehilangan pola ditangguhkan juga dalam kasus-kasus tertentu. Anda selalu dapat membuat satu di atas Janji ES6:
sumber
Terima kasih kepada semua orang yang memposting di utas ini. Saya membuat modul yang menyertakan objek Defer () yang dijelaskan sebelumnya serta beberapa objek lain yang dibangun di atasnya. Mereka semua memanfaatkan Janji dan sintaksis Panggilan balik yang rapi untuk mengimplementasikan komunikasi / penanganan acara dalam suatu program.
Antrian: Antrian eksekusi berdasarkan Chaining janji.
rp = require("repeatable-promise")
https://github.com/CABrouwers/repeatable-promise
sumber
Saya menulis lib kecil untuk ini. https://www.npmjs.com/package/@inf3rno/promise.exposed
Saya menggunakan pendekatan metode pabrik lain menulis, tapi saya mengesampingkan
then
,catch
,finally
metode juga, sehingga Anda dapat menyelesaikan janji asli oleh mereka juga.Menyelesaikan Janji tanpa pelaksana dari luar:
Balap dengan setTimeout pelaksana dari luar:
Ada mode tanpa konflik jika Anda tidak ingin mencemari namespace global:
sumber
Saya membuat perpustakaan bernama
manual-promise
yang berfungsi sebagai penggantiPromise
. Tidak ada jawaban lain di sini yang akan berfungsi sebagai pengganti penggantiPromise
, karena mereka menggunakan proksi atau pembungkus.yarn add manual-promise
npn install manual-promise
https://github.com/zpxp/manual-promise#readme
sumber
Bagaimana dengan membuat fungsi untuk membajak tolak dan mengembalikannya?
sumber
Saya telah mengumpulkan inti yang melakukan pekerjaan itu: https://gist.github.com/thiagoh/c24310b562d50a14f3e7602a82b4ef13
inilah cara Anda harus menggunakannya:
sumber
pertama-tama aktifkan --allow-natives-syntax di browser atau node
sumber
Hanya solusi lain untuk menyelesaikan Janji dari luar
Pemakaian
sumber