Mongoose: Kemampuan untuk menentukan ES6 mana yang menjanjikan penggunaan luwak perpustakaan

Dibuat pada 17 Feb 2015  ·  45Komentar  ·  Sumber: Automattic/mongoose

Lihat diskusi di #1699

Komentar yang paling membantu

Yup require('mongoose').Promise = global.Promise akan membuat luwak menggunakan janji asli. Anda seharusnya dapat menggunakan konstruktor janji ES6 apa pun, tetapi saat ini kami hanya menguji dengan native, bluebird, dan Q

Semua 45 komentar

Sangat menantikan untuk dapat menggunakan Promise.all(), untuk melakukan sesuatu setelah semua pekerjaan database selesai.

:+1:

Satu hal yang tidak terlalu jelas di https://github.com/LearnBoost/mongoose/issues/1699 adalah implementasi apa yang akan menjadi default.

Mengingat bahwa ini bukan rilis yang mundur, mpromise harus menjadi default, tetapi Anda akan dapat menggantinya.

+1

:+1:

Apakah ada cabang tempat ini diretas? Saya tidak tahan dengan aliran penanganan kesalahan dengan mpromise dan saya akan membuka sumbernya untuk melihat apa yang akan terjadi.

janji:

  query.exec()
    .then(function(ou) {
      if(!ou) {
        return next(new errors.http.NotFound('The specified OU was either not found, or your credentials lack the required permissions to view it.'));
      }

      res.send(ou);
    }, next)
    .end(next);

Harus menangani penolakan dan juga meletakkan end di sana. Tanpa end , pengecualian (misalnya, saya memiliki kelas NotFound yang salah eja) diam-diam ditelan dan hanya menunjukkan kios.

burung biru:

  query.exec()
    .then(function(ou) {
      if(!ou) {
        return next(new errors.http.NotFound('The specified OU was either not found, or your credentials lack the required permissions to view it.'));
      }

      res.send(ou);
    })
    .catch(next);

Melakukan promisifyAll(require('mongoose')) tampaknya masih berfungsi dengan Mongoose 4 sejauh ini. Apakah tes regresi yang mencakup ini terlalu ditargetkan?

Tidak saat ini. Sebagian besar pekerjaan akan berlangsung di modul kareem sesuai #2754 dan vkarpov15/kareem#2, karena itu akan memungkinkan kita untuk membunuh dua burung dengan satu batu dan menghapus omong kosong yang benar-benar berantakan yang ditulis untuk membuat kait dan janji bekerja sama. Jangan ragu untuk mencobanya, saya terbuka untuk PR.

Tetapi mengapa kita harus tetap mendukung perpustakaan janji lainnya? Spesifikasi ES6 Promises sekarang sangat kokoh dan akan tetap ada. Tidak bisakah kita menggunakan Janji ES6 murni, dengan polyfill yang dimuat ketika mereka tidak tersedia di versi node yang lebih lama?

Jika demikian, saya dapat mencobanya.

Intinya adalah Anda akan dapat menggunakan perpustakaan janji yang kompatibel dengan ES6 apa pun yang Anda suka. Banyak orang masih banyak berinvestasi dalam bluebird, ketika, q, rsvp, dll dll. Dan masing-masing perpustakaan itu memiliki kebiasaan khusus sendiri yang tidak akan ditangkap oleh polyfill generik.

Saya terbuka untuk saran alternatif - Saya tidak terlalu suka atau menggunakan janji, fitur ini dimotivasi oleh fakta bahwa ada segunung masalah yang melibatkan orang yang meminta "dukungan fitur bluebird X di mpromise" atau "dukungan rsvp.js asli " dan membiarkan orang membawa perpustakaan janji mereka sendiri ke pesta adalah cara termudah untuk menutup masalah ini.

Saya mengerti apa yang kamu maksud. Saya pengguna besar dan pendukung Promises. Saya pikir itu harus dipertimbangkan untuk menegakkan standar.
Janji A+ telah dipilih sebagai pilihan untuk ES6. Saya menyarankan polyfill untuk memastikan dukungan untuk versi node yang tidak kompatibel dengan ES6 (mis. https://github.com/jakearchibald/es6-promise).

Itu harus di tangan perpustakaan janji lain agar kompatibel dan dapat dicampur dengan janji ES6.

EDIT:
Dan tidak akan ada kerusakan di API saat ini atau apakah saya melewatkan sesuatu?

Spesifikasi Promises/A+ sangat berbeda dari ES6 promise spec, yang pada gilirannya berbeda dari perpustakaan promise yang saya cantumkan di komentar sebelumnya. Meskipun akan baik bagi saya jika banyak sekali perpustakaan janji semua dikonsolidasikan ke dalam ES6, saya ragu itu akan pernah terjadi, karena keindahan open source adalah bahwa beberapa orang yang menyukai janji akan menginginkan fitur tambahan dan akan menulis janji mereka sendiri perpustakaan.

Tidak ada perubahan yang melanggar untuk API saat ini, yang saya pikirkan adalah cara untuk mengatakan mongoose.set('Promise', require('bluebird')); atau sesuatu seperti itu, jadi itu akan menjadi keikutsertaan dan mpromise akan menjadi default.

Oh ya, maaf atas kesalahan itu.
Saya telah melihat implementasi saat ini, dan perpustakaan janji lainnya.

Saya pikir saya bisa membuat sesuatu seperti ini berfungsi:

mongoose.set('Promise', Promise);

mongoose.set('Promise', require('bluebird'));

mongoose.set('Promise', require('q').defer());

mongoose.set('Promise', require('when').defer());

// and so on...

Jadi pada dasarnya, Anda harus mengekspos ke Mongoose janji objek pilihan Anda yang memiliki metode resolve dan reject .

Apakah ini yang Anda pikirkan? Jika demikian, saya akan mengerjakan permintaan tarik.

EDIT:
Rasanya sangat konyol untuk menulis mongoose.set('Promise', Promise); . Saya pikir ES6 harus menjadi default, dengan kemungkinan untuk menggunakan perpustakaan pilihan Anda (dan mpromise setiap kali ES6 Promises tidak tersedia).

Tentu, saya akan menghargai bantuan Anda. Bagian yang sulit adalah 1) membuatnya berfungsi dengan kait - lihat vkarpov15/kareem#2, dan 2) membuatnya kompatibel dengan mpromise.

Juga, ulang: Q, kami akan menggunakan require('q').Promise karena itulah sintaks Q yang paling dekat dengan spesifikasi ES6

Terima kasih atas masukan Anda, akan bekerja di atasnya. Apakah Anda lebih suka pull request yang bersaing atau PR yang sedang berlangsung?

Menyelesaikan lebih baik, tetapi saya selalu memiliki beberapa saran. Beri tahu saya jika Anda buntu

+1 untuk fitur ini. saya ingin menggunakan dengan bluebird

Maaf karena menjadi drastis - tetapi pendekatan alternatif adalah dengan tidak lagi memberikan dukungan janji sama sekali. Itu akan membungkam siapa pun yang menggunakan janji meminta dukungan dari perpustakaan lain.
Orang yang menggunakan perpustakaan janji yang kuat seperti bluebird dapat tetap menggunakannya karena Anda mengekspos API panggilan balik dan bluebird dapat dengan mudah membungkusnya dengan biaya 0 - sebenarnya kemungkinan besar karena Anda tidak tahu atau menggunakan janji (seperti yang Anda katakan) kemungkinannya adalah itu akan lebih lambat dan lebih rentan terhadap kesalahan untuk mendukungnya secara manual.

@benjamingr 100% tidak setuju. Sekarang dengan iojs dan NodeJs bergabung ke Node 3.0, akan ada dukungan untuk ES6 Promises and Generators.

Menjatuhkan dukungan akan menjadi langkah mundur yang besar.

Yaitu, Promise.promisifyAll(require("mongoose")) membuat pembungkus cepat (lebih cepat daripada upaya manual yang mungkin) untuk Mongoose yang merupakan keluhan standar dan mengelilingi semua API tanpa Anda harus melakukan apa pun tentangnya. Bahkan, Anda dapat melakukan Promise.promisifyAll pada objek ekspor sendiri dan mengekspos janji bluebird dan metode janji ganda (save - saveAsync) secara gratis dan kemudian mengatakan Anda mengekspos antarmuka janji bluebird tanpa harus melakukan pekerjaan yang sebenarnya.

Jadi, sementara saya menggunakan janji bluebird sendiri - saya pikir semua ini dapat diperbaiki dengan bagian dalam dokumen daripada memperumit kode Anda dengan mengkodekan ke dua antarmuka.

@albertorestifo kecuali tidak ada yang benar-benar akan dijatuhkan. Saya sangat menyadari apa yang dijanjikan (lebih dari 1500 poin dan 500 jawaban di stack overflow: P) dan saya bahkan bertanggung jawab atas beberapa bagian cara kerjanya di io.js (seperti https://github.com/ nodejs/io.js/issues/256).

Itu tidak mengubah fakta, saya percaya bahwa karena @vkarpov15 tidak menggunakan janji, dia tidak harus mendukungnya di perpustakaannya _terutama karena itu tidak membawa manfaat apa pun daripada menggunakan janji dengannya_. Anda dapat menggunakan janji dengan luwak dengan mudah bahkan jika itu tidak memberikannya - luwak mengimplementasikan dukungan secara internal lebih untuk dipertahankan, kemungkinan lebih lambat, dan lebih rentan kesalahan. @vkarpov15 dapat terus bekerja pada API panggilan balik dan pengguna janji dapat membungkus Mongoose dengan janji dengan satu liner yang mudah.

@benjamingr yang seandainya seseorang menggunakan perpustakaan Promise eksternal. Saya tetap berpegang pada yang ada di spesifikasi, dan Anda tahu betul, itu tidak memiliki pembungkus.

Saya melihat poin Anda. Mendukung keduanya menciptakan kekacauan besar. Saya pribadi membenci panggilan balik, jadi saya akan membatalkannya. Mungkin harus ada dua repositori terpisah, satu menggunakan generator dan janji, yang lain menggunakan panggilan balik. Keduanya akan mempertahankan struktur yang sama dan API sedekat mungkin.

@benjamingr yang seandainya seseorang menggunakan perpustakaan Promise eksternal. Saya tetap berpegang pada yang ada di spesifikasi, dan Anda tahu betul, itu tidak memiliki pembungkus.

Jika Anda memilih untuk menggunakan implementasi yang lambat, lebih sulit untuk di-debug, dan kurang kaya fitur yang tentu saja merupakan pilihan Anda: P tetapi bagaimana itu terkait dengan pembungkusnya? Sangat mudah untuk menulis pembungkus yang mirip dengan promisifyAll bluebird menggunakan janji asli*.

Jika Anda menginginkan janji - versi Mongoose yang diaktifkan sebagai paket terpisah, inilah cara Anda melakukannya:

  • Langkah 1, buka editor favorit Anda atau hanya editor yang Anda sukai.
  • Langkah 2, ketik module.exports = require("bluebird").promisifyAll(require("mongoose"))
  • Langkah 3, buat file package.json yang sesuai, publikasikan ke npm
  • Langkah 4, puluhan ribu unduhan.

Sekarang, saya tahu apa yang Anda pikirkan "ini tidak menggunakan janji asli", Anda masih dapat menghapus setiap metode kecuali then dan catch dari prototipe janji dan all dan race dari Promise dan berakhir dengan API yang sama - atau Anda dapat memberi tahu orang-orang bahwa Anda mengekspor janji asli - mereka tidak akan tahu karena itu hanya dua implementasi Janji/A+, Saya berjanji ;)

(* menulisnya dengan cepat lebih sulit di tingkat pengguna karena tidak ada cara cepat untuk membuat janji saat ini, itulah sebabnya io.js kemungkinan akan mengekspor fungsi promisify itu sendiri pada akhirnya - yang mengatakan dengan mengambil konstruktor janji yang Anda paksakan tetap lambat).

Itu jelas merupakan alternatif yang layak. Saya ingin menepati janji, karena, suka atau tidak, begitulah cara pengguna akan menggunakan luwak, jadi kami mungkin juga memiliki cakupan pengujian yang solid untuk itu, sehingga kami dapat menunjukkan dan mengatakan "inilah caranya anda menggunakan perpustakaan janji X dengan luwak". Kelemahan ketika Anda memutuskan sesuatu ke dalam modul terpisah adalah sulit untuk mengatakan "ok versi janji luwak ini hanya berfungsi dengan luwak 3.8, yang ini berfungsi dengan luwak >= 4.1" dan sulit bagi luwak untuk menghindari melanggar pembungkus janji yang menyeluruh .

Itu jelas merupakan alternatif yang layak. Saya ingin menepati janji, karena, suka atau tidak, begitulah cara pengguna akan menggunakan luwak, jadi kami mungkin juga memiliki cakupan pengujian yang solid untuk itu,

Mengapa Anda ingin/membutuhkan cakupan tes untuk itu? Tidak ada gunanya menguji janji sendiri dalam kode Anda - perpustakaan sudah memiliki tes - ini seperti menguji modul http saat Anda menggunakannya.

dan sulit bagi luwak untuk menghindari melanggar pembungkus janji yang menyeluruh.

Bluebird melakukan sesuatu yang sangat sederhana - ia menemukan prototipe dan kemudian menambahkan metode dengan akhiran Async kepada mereka - ini sangat sederhana dan bekerja dengan baik dalam praktiknya - ini adalah satu baris dengan sebagian besar perpustakaan termasuk Mongoose dan tidak rusak bahkan sekali untukku dalam satu tahun terakhir.

Saya tidak yakin mengapa Anda ingin mempertahankan banyak kode penyambungan yang berpotensi rawan kesalahan, secara manual harus mendukung dua API dengan kasing tepinya terdengar seperti banyak pekerjaan dan Anda dapat memecahkan banyak hal saat Anda pergi - Anda bisa "pinjam" kode promisifyAll bluebird dan sesuaikan agar berfungsi dengan perpustakaan janji lainnya (bagaimanapun juga itu open source) tetapi saya pasti tidak akan melakukannya secara manual.

"ok versi janji luwak ini hanya berfungsi dengan luwak 3.8, yang ini berfungsi dengan luwak >= 4.1" dan sulit bagi luwak untuk menghindari melanggar pembungkus janji yang menyeluruh.

Nah, maukah Anda memberi saya contoh perubahan besar yang harus terjadi jika promisifikasi otomatis?

1) Saya ingin menguji hal-hal dengan cara pengguna menggunakannya.

2) Saya ingin bermalas-malasan dan menghindarinya, tetapi seperti yang saya pahami, sebagian besar perpustakaan janji lainnya tidak memiliki promisifyAll yang setara. Saya berasumsi inilah mengapa "mendukung fitur Xpromise Y" adalah permintaan fitur luwak paling populer. Selanjutnya, kami tidak memiliki niat untuk menulis ulang janji Bluebird, hanya membuat fungsi luwak mengembalikan janji secara asli.

3) Tergantung pada penerapan promisifikasi dan bagaimana Anda menggunakannya :)

1) Saya ingin menguji hal-hal dengan cara pengguna menggunakannya.

Apa yang Anda maksud dengan menguji cara pengguna menggunakannya? Bisakah Anda menunjukkan analogi untuk panggilan balik?

2) Saya ingin bermalas-malasan dan menghindarinya, tetapi seperti yang saya pahami, sebagian besar perpustakaan janji lainnya tidak memiliki promisifyAll yang setara. Saya berasumsi inilah mengapa "mendukung fitur Xpromise Y" adalah permintaan fitur luwak paling populer. Selanjutnya, kami tidak memiliki niat untuk menulis ulang janji Bluebird, hanya membuat fungsi luwak mengembalikan janji secara asli.

Anda tidak perlu menulis ulang, Anda dapat menerimanya - ini tidak generik karena implementasi generik akan lebih lambat.

Ini juga bukan kemalasan untuk tidak secara manual mengimplementasikan fitur yang tersedia secara luas. Apakah NodeJS malas karena tidak memasukkan express ke dalam inti? Apakah TC39 malas karena tidak meletakkan garis bawah di inti? Dengan tetap berpegang pada konvensi (panggilan balik), Anda memberi pengguna kemampuan untuk menggunakan primitif konkurensi mana pun yang mereka inginkan.

3) Tergantung pada penerapan promisifikasi dan bagaimana Anda menggunakannya :)

Nah, promisifikasi bluebird, atau Q's atau When's - implementasinya bervariasi tetapi semuanya melakukan hal yang sama - jadi pilih saja yang Anda suka. Aku hanya ingin tahu bagaimana itu akan pecah.

Ada satu hal yang saya lewatkan dalam diskusi ini di sini:

Jika luwak mengembalikan janji standar (dengan arti standar implementasi asli ES6), bukankah itu harus kompatibel dengan perpustakaan Promise yang kompatibel dengan ES6? Saya dapat melakukan Promise.all([model.query().exec(), ...]) dengan baik, serta bluebird, q, jika setara.

Jadi, mengapa tidak mengembalikan panggilan balik dan janji standar (seperti yang dilakukan sekarang, tetapi "menyingkirkan" mpromise) dan membiarkan pengguna menggunakan perpustakaan janji favoritnya? Atau apakah saya melewatkan sesuatu di sini?

@albertorestifo yah, janji asli lambat saat ini dan itu akan memakan waktu, berpotensi bertahun-tahun sebelum mereka mencapai paritas dengan perpustakaan userland - jadi terutama itu.

@benjamingr Anda membuat beberapa poin bagus. Poin utama dari janji luwak adalah untuk memungkinkan Anda menggunakan yield dengan operasi asinkron luwak tanpa perpustakaan lain, itulah sebabnya kami menepati janji untuk masa mendatang. IMO itu sesuatu yang harus benar-benar menjadi bagian dari inti luwak ke depan.

Apakah Q atau Kapan memiliki kemampuan promisifikasi?

Apakah Q atau Kapan memiliki kemampuan promisifikasi?

Ya, hampir setiap perpustakaan janji yang tersebar luas yang saya tahu menawarkan semacam janji:

Inilah saatnya: https://github.com/cujojs/when/blob/master/docs/api.md#nodeliftall
Inilah T: https://github.com/kriskowal/q/wiki/API-Reference#qnfbindnodefunc -args

Janji asli belum memilikinya, tetapi itu adalah sesuatu yang sedang dikerjakan - setelah jalur cepat untuk membuat janji (yaitu - bukan konstruktor janji) ada maka NodeJS kemungkinan akan mendukungnya secara inti untuk janji asli (karena bisa' t dilakukan _fast_ di userland).

Poin utama dari janji luwak adalah untuk memungkinkan Anda menggunakan hasil dengan operasi asinkron luwak tanpa perpustakaan lain

Anda memerlukan perpustakaan untuk menggunakan yield secara bermakna dengan janji. Jika Anda dapat menulis sendiri 9 LoC yang memompa generator sebagai fungsi asinkron, Anda pasti dapat menulis promisify - dan jika Anda seperti kebanyakan pengguna, Anda tetap menggunakan perpustakaan untuk itu.

Saya benar-benar melihat keinginan/kebutuhan untuk mengizinkan janji di Mongoose, itu adalah jalan ke depan dan bagaimana bahasa melakukan konkurensi sekarang, tetapi sejujurnya saya berpikir bahwa melakukannya secara manual metode demi metode akan menyakitkan. Mungkin bermanfaat untuk mendemonstrasikan bagaimana hal itu dilakukan menggunakan perpustakaan di bagian "menggunakan dengan janji" atau "menggunakan dengan generator" dalam dokumentasi.

Masalahnya adalah kita sudah melakukannya metode demi metode, kita hanya perlu memodifikasi pembungkus janji internal. Either way, kami tidak dapat menghapus janji dari inti hingga 5.0. Saya setuju dengan gagasan untuk mencelanya, @benjamingr memang membuat beberapa argumen bagus yang harus saya pertimbangkan dengan cermat, tetapi saya pikir langkah selanjutnya adalah #2688.

Anda jelas memiliki lebih banyak pengalaman dengan Mongoose dan yang lebih penting adalah penggunanya - jadi saya mengerti pilihan itu. Terima kasih banyak telah mendengarkan saya.

Saya mengetik "nya" tetapi iPhone saya merasa harus mengoreksinya secara otomatis menjadi "itu" dan GitHub merasa bahwa mengedit komentar bukanlah kasus penggunaan yang menarik. Maaf untuk komentar ganda-spam :)

Anda dapat mengedit komentar di situs web jika Anda mengklik pensil di kanan atas komentar Anda.

Saya selalu terbuka untuk debat hangat yang bagus, terutama yang mengajari saya sesuatu yang baru :beers: Saya mungkin akan melakukan ping nanti untuk membahas lebih banyak :)

Masa depan adalah milik janji asli, tampaknya. Mongoose adalah standar industri untuk operasi mongo, itu benar-benar valid untuk mengandalkan janji standar juga.

Janji standar pasti akan matang dan menjadi lebih luas daripada kerangka kerja apa pun. +1 yang rendah hati untuk menggunakannya.

@iliakan mungkin di masa depan. Saya tidak berharap janji asli menjadi "standar" paling cepat hingga pertengahan 2016, berbagai perpustakaan janji yang terfragmentasi terlalu mengakar dan memiliki terlalu banyak kebiasaan halus. Either way, luwak tidak dapat beralih ke 'asli secara default' tanpa perubahan besar-besaran ke belakang.

@vkarpov15 tentu saya mengerti.

Apa yang bisa bermanfaat sementara itu - halaman sederhana yang menguraikan ketidaksesuaian utama antara janji-janji dan janji-janji asli. Setidaknya hal-hal yang tidak boleh Anda coba dengan mpromise ;)

Apakah saya benar bahwa tidak ada catch saat ini, dan hanya itu batasannya?

Tidak tahu, belum benar-benar menggali ES6 API. mpromise mengimplementasikan Janji/A+ dan tidak ada yang lain, yang berarti tidak ada .catch(), tidak ada jejak tumpukan yang panjang, dll. dll. Pada dasarnya, apa pun yang bukan .then() berada di luar cakupan implementasi mpromise.

Secara umum, sesuatu yang mengimplementasikan Promises/A+ juga mengimplementasikan janji ES6 dari perspektif tingkat tinggi, tetapi kebalikannya tidak benar. Promises/A+ sangat spesifik tentang detail implementasi tingkat rendah, misalnya, bluebird tidak sepenuhnya mematuhi Promises/A+, dan saya tidak yakin tentang perpustakaan janji umum lainnya tetapi saya yakin mereka tidak mematuhi spesifikasi di cara unik mereka sendiri. Itulah yang akan membuat ini sangat rumit.

Maksudmu, sekarang bisa menggunakan bluebird dan janji asli?

Yup require('mongoose').Promise = global.Promise akan membuat luwak menggunakan janji asli. Anda seharusnya dapat menggunakan konstruktor janji ES6 apa pun, tetapi saat ini kami hanya menguji dengan native, bluebird, dan Q

@vkarpov15 Ini bagus! Terima kasih banyak!

@vkarpov15 Terima kasih banyak! Kerja bagus!

Ya tentu saja. Itu keren sekali! :)

@vkarpov15 Ini sangat bagus

Apakah halaman ini membantu?
0 / 5 - 0 peringkat