JavaScriptにコンパイルする(まだ別の)言語を作成しようとしています。私が持たせたい機能の1つは、JavaScriptの非同期操作を同期的に(正確には同期ではなく、もちろんメインスレッドをブロックせずに)実行できることです。より少ない話、より多くの例:
/* These two snippets should do exactly the same thing */
// the js way
var url = 'file.txt';
fetch(url)
.then(function (data) {
data = "(" + data + ")";
return sendToServer(data);
}).then(function (response) {
console.log(response);
});
// synchronous-like way
var url = 'file.txt';
var response = sendToServer("(" + fetch(url) + ")");
console.log(response);
それをJSにコンパイルする最もエレガントな方法は何ですか?
重要度でソートされた基準:
- パフォーマンス
- 下位互換性
- コンパイルされたコードの可読性(それほど重要ではない)
それを実装するいくつかの可能な方法があり、それらの3つは私の頭に浮かびました:
Promiseの使用:
f(); a( b() );
に変わりますf().then(function(){ return b() }).then(function(x){ a(x) });
- 長所:実装が比較的簡単で、ES3にポリフィル可能
- 短所:関数呼び出しごとに新しい関数とProxyインスタンスを作成する
-
f(); a( b() );
に変わりますyield f(); tmp = yield b(); yield a( tmp );
- 長所:より良いJavaScript
- 短所:すべてのステップでプロキシ、ジェネレータ、イテレータを作成し、ポリフィルも不可
- 編集:実際には、別のリコンパイラー(例:Regenerator)を使用してポリフィルできます。
同期XMLHttpRequestの使用:
- コード内の別の場所からの別の呼び出しまで待機するサーバースクリプトを要求する
- 長所:コードの変更は事実上なく、実装が非常に簡単
- 短所:サーバースクリプトが必要(=>移植性なし、ブラウザーのみ); さらに、同期XMLHttpRequestはスレッドをブロックするため、まったく機能しません
- 編集:それは実際にはワーカー内で機能します
主な問題は、実行時まで関数が非同期かどうかわからないことです。その結果、少なくとも動作する2つのソリューションは、純粋なJSよりもはるかに遅くなります。だから私は尋ねます:
実装するより良い方法はありますか?
回答から:
Awaitキーワード(@ MI3Guy)
- C#の方法(これは良いことです!)
- 新しいキーワードを導入します(これは関数(1st-class-citizen)として偽装することができます。たとえば、プログラマーが引数としてそれを渡そうとした場合にスローされます)
- その関数が非同期であることをどのように知るのですか?他のキーワードはありません!
await
キーワードを含むすべての関数が非同期になりますか?- コードがに到達する
await
と、promiseを返しますか?そうでなければ、通常の関数として扱いますか?
f(); a( b() );
向けるだろうf().then(b).then(a);
な機能を囲んでいないあなた。
synchronously (without blocking the thread, of course)
あなたはその言葉を使い続けます。同期的には「スレッドをブロックする」