現在のfileManager
loadFile
またはloadFileSync
を呼び出すことをどのように決定しますか? このコードによると、 isSync
パラメータを設定する必要があります。 ただし、 getFileManager
呼び出しを短く検索すると、このオプションはlib/less/functions/data-uri.js
のみ使用されていることがわかります。
render()
呼び出すときに、このオプションを明示的に設定することはできますか?
isSyncは、レンダリングするオプションオブジェクトに渡すことができます。 data-uriは常に
関数を非同期にすることはできないため、同期します。
しかし、 importManager
はgetFileManager
オプションを渡しません...
ここで行われます
そのオプションは少ないコアによって無視され、ブラウザにのみ固有であるためです。 そのため、ブラウザは常に非同期と呼ばれ、オプションによっては同期または非同期メカニズムを使用してファイルを取得する場合があります。
それがどのように混乱しているのかがわかります。 問題が発生していますか?
すぐにわかることの1つは、ページの読み込み時にオプションの影響を受けるため、後で設定したり、オプションとして渡したりすると無視されるということです。
まあ、おそらく私は私のユースケースを説明する必要があります:
webpack用のless-loaderを作成しました。 webpackには独自の解決メカニズムがあるため、プラグインを使用して、ファイルマネージャーを介してより少ないファイル解決にフックします。
Webpackは同期ローダーと非同期ローダーをサポートしていますが、すべてのファイルを同期または非同期にレンダリングするように指示する方法が見つかりませんでした。 現在、常にloadFile
呼び出します。 したがって、同期コンパイルが要求されたときに、ダーティハックを使用してloadFileSync
を呼び出しました。 幸いなことに、コールバックが同期的に呼び出された場合、同期的に機能することは少なくなります(もちろん、通常の状況では実行しないでください)。
分かりました...
非同期オプションをより少ないコンテキストに移動し、それを使用して、提案どおりにどの呼び出しを行うかを決定する必要があると思います。 ブラウザのファイルマネージャにいくつかの変更が必要な場合がありますが、それは良いリファクタリングになると思います。
いいね!
1つだけ問題があります: callback
を受け入れている間に同期的に何かを行うことは非常に珍しいことです( render
関数が行うように)。 次のようなsync
オプションを提案しています。
less.render(
input,
{ ... sync: true ... },
function (err, result) {
}
);
?
コールバックが同期的に呼び出されるのはおかしいです。 私はこのようなAPIを期待しています:
// async
less.render(input, option, callback);
// sync
var result = less.renderSync(input, option);
はい、あなたは正しいです、それはより良いです。
+1
これは、コールバックのみでコードの実行を制限しないようにrenderSync
実装を検討することも非常に役立つようです。 コールバックスコープでは、 console.err
やthrow new Error()
などの多くのメソッドや意図的なJavaScriptエラーはコンソールに何も出力せず、コードの実行を停止するだけで、追跡できないバグが発生する可能性があります。 私はこの振る舞いが起こらないはずだと思います。
私の特定のケースでは、 renderSync
はコマンドラインユーティリティで使用され、promiseを使用してコールバックフローを制御してすべての出力とエラーが毎回順番に出力されるようにするのではなく、renderSyncを使用します。それについて心配する。
(問題自体を侮辱するのではなく、それが実際よりもさらに奇妙にならないようにするためです):
コールバックが同期的に呼び出されるのはおかしいです。
これは誇張です...コードのこの行では、構成が非同期に設定されているとは想定していませんね。
コールバックは単なるコールバックであり、それ自体は同期/非同期のものとは何の関係もありません。
PS詳細を明確にするために:
@kwketh
このless.render
フォームは何年も前から存在していました。何もないところから取り出して変更するだけでは、無数のスニペットを壊すことができません。
@ seven-phases-max
あなたの答えに感謝します、それらはすべて役に立ちます。 コールバックに関するすべての点に同意します。 私は.render
コードを非常に簡単に調べましたが、あなたは正しいです、それが書かれている形式、それはすべてコールバックを中心に展開しており、 renderSync
を持つのは簡単でも合理的でもないようです。
私の問題はどういうわけか異なりますが、関連しています(https://github.com/less/less.js/issues/2546)。 renderSync
機能を実装すると問題は解決しますが、最終的な解決策にはなりません。
ざっと見てもいいですか。 本当にありがたいです。
ありがとう。
誰かがノードを使いすぎています
まあ、それは本当です:grin:
ただし、ノードのコールバック規則は十分に確立されています。 この場合、コールバックは常に非同期で呼び出されると思います。
さらに:エラーが発生した場合、エラーはどのように処理されますか? (ほとんどの同期APIのように)スローされますか、それともコールバックへの引数として渡されますか?
現在のAPIがあいまいなだけです(少なくとも私見)
renderSync
もうありますか? そうでない場合、同期render
回避策はありますか?
編集:Nvm。 これに遭遇する将来の人のために、これは私がしたことです:
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;
};
この機能は実際に実装されていますか? ドキュメントはありますか? async
オプションしか見つかりません。
実際にサポートされている場合はIdkですが、現在私が行ったことはうまくいくことを知っているので、肩をすくめる
@Aarilightどうもありがとうございました、あなたのコードは大いに役立ちました
この同期コールバックの動作は、実際には直感に反します:confused:
@Aarilightそれは私には機能しません=(
私は試した
less.render(css, {sync : true}, (e, result) =>{
if(e) {
console.error(e)
}
output = result;
return result
});
記録された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')
そして、いくつかのファイルについては、1、8、次に2、3、4、5、6、7が表示されます
-1を使用して、レンダリングをrender
とrenderSync
に分割します。 厄介なのはNode.jsの規則です。 また、同期オプションをgrunt / gulp / accordに送信したり、JSオブジェクトを指定された関数に渡すlessに統合された他のワークフローを送信したりすることはできません。 IMO非同期オプションを使用する場合は、オプションのコールバックを渡すことは問題ありません。
別のオプション:ライブラリが実行し始めるのを見たのは、どちらの場合でも実際に約束を返すことです。 次に、sync / asyncの間で変更されるのは、promiseが実行されたときだけですが、結果を処理するコードはまったく同じです。
そしてところで:
{sync: true}
そのようなオプションはありません。
-1は、renderをrenderとrenderSyncに分割します。 厄介なのはNode.jsの規則です。
それは完全に主観的な視点ではありませんか? 非同期と同期を1つの関数に組み合わせたIMHOは、(いくつかの例外を除いて)ひどいアンチパターンです。 条件付きステートメントが散らかっていて、保守が難しく、1つのことをうまく実行する明確に定義され、文書化された関数よりもユーザーを混乱させるコードを作成します。 ちょうど私の2c
それは完全に主観的な視点ではありませんか?
はい。
とにかく、私の他の点は主観的ではありません。 つまり、Lessは、関数が分割された場合に更新が必要になる可能性のあるビルドプロセスで使用されます。 たとえば、現在1つのプロジェクトで使用しているAccord(https://github.com/jenius/accord)は、さまざまなコンパイラを1つのAPIに抽象化し、通常、エンジンが必要とする関数にオブジェクトを渡します。 したがって、開発者が指定するLessオプションに基づいて使用する関数を切り替えることはおそらく大したことではありませんが、影響するライブラリの数はわかりません。 知っておくべきことです。
今のところ、オプションにsyncImport: true
を追加すると、これが修正されました。
(ドキュメントにはありません...ソースコードで偶然見つけたのは幸運でした)
この問題は、最近のアクティビティがないため、自動的に古いものとしてマークされています。 それ以上のアクティビティが発生しない場合は閉じられます。 貢献していただきありがとうございます。
最も参考になるコメント
renderSync
もうありますか? そうでない場合、同期render
回避策はありますか?編集:Nvm。 これに遭遇する将来の人のために、これは私がしたことです: