Bagaimana less memutuskan untuk menelepon loadFile
atau loadFileSync
dari fileManager
? Menurut kode ini memerlukan isSync
-parameter untuk disetel. Tetapi pencarian singkat untuk panggilan ke getFileManager
mengungkapkan bahwa opsi ini hanya digunakan oleh lib/less/functions/data-uri.js
.
Apakah mungkin untuk mengatur opsi ini secara eksplisit saat memanggil render()
?
isSync dapat diteruskan dalam objek opsi untuk dirender. data-uri selalu
sinkronkan karena fungsi tidak dapat asinkron.
Tetapi importManager
tidak memberikan opsi apa pun ke getFileManager
...
Ini dilakukan di sini
Itu karena opsi itu diabaikan oleh lebih sedikit inti dan hanya khusus untuk browser. Jadi browser selalu dipanggil async dan mungkin tergantung pada opsi menggunakan mekanisme sinkronisasi atau asinkron untuk mendapatkan file.
Saya bisa melihat bagaimana itu membingungkan. Apakah itu menyebabkan masalah?
Satu hal yang saya lihat segera adalah bahwa itu hanya akan dipengaruhi oleh opsi saat memuat halaman, jadi jika disetel setelahnya atau diteruskan sebagai opsi, itu akan diabaikan..
Yah, mungkin saya harus menjelaskan kasus penggunaan saya:
Saya telah menulis less-loader untuk webpack . Karena webpack memiliki mekanisme penyelesaian sendiri, saya menggunakan plugin untuk menghubungkan penyelesaian file yang lebih sedikit melalui pengelola file.
Webpack mendukung pemuat sinkronisasi dan asinkron tetapi saya belum menemukan cara untuk memberi tahu lebih sedikit untuk membuat semua file disinkronkan atau tidak sinkron. Saat ini selalu memanggil loadFile
. Jadi saya menggunakan retasan kotor untuk memanggil loadFileSync
ketika kompilasi sinkron diminta. Untungnya less berfungsi secara sinkron ketika panggilan balik dipanggil secara sinkron (yang tentu saja tidak boleh dilakukan dalam keadaan normal).
Jadi begitu...
Saya pikir kita harus memindahkan opsi async untuk berada pada konteks yang lebih sedikit, kemudian menggunakannya untuk menentukan panggilan mana yang harus dilakukan seperti yang Anda sarankan. Mungkin perlu beberapa perubahan pada pengelola file browser, tetapi saya pikir ini akan menjadi refactor yang bagus.
Dingin!
Hanya ada satu masalah: Sangat tidak biasa untuk melakukan sesuatu secara serempak saat menerima callback
(seperti yang dilakukan fungsi render
). Anda menyarankan opsi sync
-seperti ini:
less.render(
input,
{ ... sync: true ... },
function (err, result) {
}
);
?
Imho aneh jika panggilan balik dipanggil secara serempak. Saya mengharapkan api seperti ini:
// async
less.render(input, option, callback);
// sync
var result = less.renderSync(input, option);
Ya Anda benar, itu lebih baik.
+1
Tampaknya ini juga sangat berguna untuk mempertimbangkan penerapan renderSync
agar tidak membatasi eksekusi kode dalam panggilan balik saja. Dalam cakupan panggilan balik, banyak metode seperti console.err
atau throw new Error()
atau kesalahan JavaScript yang disengaja tidak akan mencetak apa pun ke konsol, hanya menghentikan eksekusi kode, yang berpotensi menyebabkan bug yang tidak dapat dilacak. Saya membayangkan perilaku ini seharusnya tidak terjadi.
Dalam kasus khusus saya renderSync
akan digunakan dalam utilitas baris perintah dan daripada mengendalikan aliran panggilan balik menggunakan janji untuk memastikan semua keluaran dan kesalahan dicetak secara berurutan setiap kali, saya lebih suka hanya menggunakan renderSync dan tidak memiliki untuk mengkhawatirkannya.
(Tidak merendahkan masalah itu sendiri, tetapi hanya untuk memastikan itu tidak akan menjadi lebih aneh dari itu):
Imho aneh jika panggilan balik dipanggil secara serempak.
Ini berlebihan... Di baris kode ini Anda tidak menganggap konfigurasi disetel secara tidak sinkron, bukan?
Panggilan balik hanyalah panggilan balik, dengan sendirinya mereka tidak ada hubungannya dengan sinkronisasi/async.
Ok, daripada kita perlu bicara tentang istilah callback
: wink:.
Saya tahu, beberapa fungsi panggilan diteruskan ke forEach
a callback
(seperti MDN ). Saya tidak akan menyebutnya begitu, karena bagi saya panggilan balik adalah sesuatu yang dipanggil ketika tugas telah selesai.
Dan jika panggilan balik mengikuti konvensi kesalahan simpul dengan argumen pertama adalah null
atau kesalahan, maka ada alasan bagus untuk _always_ menyebutnya secara asinkron.
Saya tahu, beberapa melakukan fungsi panggilan yang diteruskan ke
forEach
a callback`
Seseorang hanya menggunakan terlalu banyak node
;) Semua orang menyebut hal ini sebagai "panggilan balik". Jadi jika salah satunya adalah tentang "fungsi panggilan balik yang dipanggil ketika tugas telah selesai", itu tidak lebih dari "panggilan balik asinkron".
Tapi tidak apa-apa, maaf, saya tidak bermaksud terdengar seperti CO dan memulai debat linguistik murni ini (hanya ingin memastikan kami berbicara bahasa yang sama dan dokumen benar-benar menyebutkan less.render
sinkron).
PS Sekedar untuk memperjelas lebih lanjut:
@kwketh
Formulir less.render
telah ada selama bertahun-tahun, Anda tidak bisa begitu saja mengambil dan mengubahnya dari nol untuk memecahkan miliaran cuplikan di luar sana.
@seven-fase-max
Terima kasih banyak atas jawaban Anda, semuanya bermanfaat. Saya setuju dengan semua poin Anda tentang panggilan balik. Saya telah melihat kode .render
dengan sangat singkat dan Anda benar, bentuk tertulisnya, semuanya berkisar pada panggilan balik dan sepertinya tidak mudah atau masuk akal untuk memiliki renderSync
.
Masalah saya entah bagaimana berbeda tetapi terkait ( https://github.com/less/less.js/issues/2546 ). Menerapkan fitur renderSync
akan menyelesaikan masalah saya tetapi itu bukan solusi akhir.
Apakah Anda keberatan melihat sekilas? Saya akan sangat menghargai.
Terima kasih.
Seseorang hanya menggunakan terlalu banyak simpul
Iya bener :grin:
Tetapi konvensi panggilan balik node sudah mapan. Saya akan menganggap panggilan balik untuk selalu dipanggil secara tidak sinkron dalam kasus ini.
Selain itu: Bagaimana kesalahan ditangani ketika ada kesalahan? Apakah itu dilempar (seperti kebanyakan API sinkronisasi) atau diteruskan sebagai argumen ke panggilan balik?
Hanya saja API saat ini ambigu (setidaknya imho)
Apakah ada renderSync
belum? Jika tidak, apakah ada solusi untuk render
sinkron?
Sunting: Nvm. Untuk setiap orang di masa depan yang menemukan ini, inilah yang saya lakukan:
less.renderSync = function (input, options) {
if (!options || typeof options != "object") options = {};
options.sync = true;
var css;
this.render(input, options, function (err, result) {
if (err) throw err;
css = result.css;
});
return css;
};
Apakah fitur ini benar-benar diterapkan? Apakah ada dokumentasi? Saya hanya dapat menemukan opsi async
-.
Idk jika itu benar-benar didukung, tapi saya tahu apa yang saya lakukan bekerja untuk saya saat ini, jadi .... mengangkat bahu
@Aarilight terima kasih banyak, kode Anda sangat membantu
Perilaku panggilan balik sinkron ini benar-benar kontra-intuitif :confused:
@Aarilight itu tidak bekerja untuk saya=(
Saya mencoba
less.render(css, {sync : true}, (e, result) =>{
if(e) {
console.error(e)
}
output = result;
return result
});
dan dicatat https://github.com/less/less.js/blob/master/lib/less/render.js
console.log('1')
this.parse(input, options, function(err, root, imports, options) {
console.log('2')
if (err) { return callback(err); }
var result;
console.log('3')
try {
console.log('4')
var parseTree = new ParseTree(root, imports);
console.log('5')
result = parseTree.toCSS(options);
}
catch (err) {
console.log('6')
return callback(err);
}
console.log('7')
callback(null, result);
});
console.log('8')
Dan saya melihat 1, 8 dan kemudian 2,3,4,5,6,7 untuk beberapa file
-1 untuk membagi render menjadi render
dan renderSync
. Ini adalah konvensi Node.js yang canggung. Dan itu tidak memungkinkan pengiriman opsi sinkronisasi ke grunt / gulp / accord atau alur kerja lain yang terintegrasi ke dalam less yang meneruskan objek JS ke fungsi yang ditentukan. IMO boleh saja meneruskan panggilan balik opsional saat menggunakan opsi async.
Pilihan lain: apa yang saya lihat mulai dilakukan perpustakaan sebenarnya mengembalikan janji dalam kedua kasus. Kemudian, semua yang berubah antara sync / async adalah ketika janji terpenuhi, tetapi kode yang menangani hasilnya persis sama.
Dan btw.:
{sync: true}
Tidak ada pilihan seperti itu.
-1 untuk memisahkan render menjadi render dan renderSync. Ini adalah konvensi Node.js yang canggung.
Bukankah itu sudut pandang yang sepenuhnya subjektif? IMHO menggabungkan async dan sinkronisasi dalam satu fungsi (dengan beberapa pengecualian) anti-pola yang mengerikan. Ini menciptakan kode yang penuh dengan pernyataan bersyarat, lebih sulit untuk dipertahankan dan bahkan lebih membingungkan bagi pengguna daripada fungsi yang jelas dan terdokumentasi yang melakukan satu hal dengan baik. hanya 2c saya
Bukankah itu sudut pandang yang sepenuhnya subjektif?
Ya.
Terlepas dari itu, poin saya yang lain tidak subjektif. Artinya, Less digunakan dalam proses build yang mungkin perlu diperbarui jika suatu fungsi dipecah. Misalnya: Accord (https://github.com/jenius/accord), yang saat ini saya gunakan untuk satu proyek, mengabstraksi berbagai kompiler ke dalam satu API, dan biasanya meneruskan objek ke fungsi apa pun yang dibutuhkan mesin. Jadi, mungkin bukan masalah besar untuk mengganti fungsi mana yang digunakan berdasarkan opsi Less yang ditentukan oleh pengembang, tetapi saya tidak yakin berapa banyak perpustakaan yang akan terpengaruh. Itu hanya sesuatu yang harus diperhatikan.
Sampai sekarang, menambahkan syncImport: true
ke opsi saya memperbaiki ini untuk saya.
(Itu tidak ada dalam dokumentasi ... Saya hanya cukup beruntung untuk menemukannya di kode sumber)
Masalah ini secara otomatis ditandai sebagai basi karena tidak ada aktivitas terbaru. Ini akan ditutup jika tidak ada aktivitas lebih lanjut yang terjadi. Terima kasih atas kontribusi Anda.
Komentar yang paling membantu
Apakah ada
renderSync
belum? Jika tidak, apakah ada solusi untukrender
sinkron?Sunting: Nvm. Untuk setiap orang di masa depan yang menemukan ini, inilah yang saya lakukan: