Less.js: Cara memicu impor sinkronisasi dan asinkron

Dibuat pada 7 Des 2014  ·  26Komentar  ·  Sumber: less/less.js

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() ?

feature request medium priority stale

Komentar yang paling membantu

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;
};

Semua 26 komentar

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

https://github.com/less/less.js/blob/32dbbee247f76af00eb7577053eccad2ee5f6110/lib/less-browser/file-manager.js#L61

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.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat

Masalah terkait

xblakestone picture xblakestone  ·  3Komentar

seven-phases-max picture seven-phases-max  ·  6Komentar

awebdev picture awebdev  ·  4Komentar

briandipalma picture briandipalma  ·  6Komentar

joe223 picture joe223  ·  4Komentar